Internet radio browser GUI for music/video streams from various directory services.

⌈⌋ ⎇ branch:  streamtuner2


Check-in [60ee1e2e12]

Overview
Comment:Moved backslash conversion and .load() override back into file browser plugin.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 60ee1e2e128db362c0ed107e632fb94c8cd7b717
User & Date: mario on 2016-12-23 22:22:38
Other Links: manifest | tags
Context
2016-12-24
20:11
Extra buttons sorted by icon name. -- Rocus check-in: dc1a3bfef9 user: mario tags: trunk
2016-12-23
22:22
Moved backslash conversion and .load() override back into file browser plugin. check-in: 60ee1e2e12 user: mario tags: trunk
21:39
Temporary workaround for file browser plugin to avoid reloading. check-in: 147d87c1e1 user: Oliver tags: trunk
Changes

Modified action.py from [93aa08299f] to [01839c79bb].

264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
264
265
266
267
268
269
270



271


272
273
274
275
276
277
278







-
-
-
+
-
-







            # no conversion
            if conf.playlist_asis:
                url = row["url"]
            # e.g. from .m3u to .pls
            else:
                url = convert_playlist(row["url"], listfmt(source), listfmt(dest), local_file=True, row=row)
            # insert quoted URL/filepath
            #return re.sub(rx, quote(url), cmd.replace("%%", "%"), 2, re.X)
            if conf.windows:
                return re.sub(rx, quote(url), cmd.replace("%%", "%"), 2, re.X)
            return re.sub(rx, quote(url), cmd.replace("%%", "%"), 2, re.X)
            else:
                return re.sub(rx, quote(url).replace("\\", "/"), cmd.replace("%%", "%"), 2, re.X)
                

    if not add_default:
        return cmd
    else:
         return "/bin/false"

Modified contrib/file.py from [af89693d25] to [6b8a1b4500].

1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







# api: streamtuner2
# title: File browser
# description: Displays mp3/oggs or m3u/pls files from local media file directories.
# type: channel
# category: local
# version: 0.2
# version: 0.3.2
# priority: optional
# status: unsupported
# depends: python:mutagen, python:id3
# config:  
#   { name: file_browser_dir, type: text, value: "$XDG_MUSIC_DIR, ~/MP3", description: "List of directories to scan for audio files." },
#   { name: file_browser_ext, type: text, value: "mp3,ogg, m3u,pls,xspf, avi,flv,mpg,mp4", description: "File type/extension filter." },
# url: http://freshcode.club/projects/streamtuner2
189
190
191
192
193
194
195







196
197
198
199
200
201
202
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209







+
+
+
+
+
+
+







        src = open(fn, "r").read() if os.path.exists(fn) else ""
        env = re.findall('^(\w+)=[\"\']?(.+?)[\"\']?', src, re.M)  # pyxdg: Your move.
        return dict(env)

    
    # don't load cache file
    cache = lambda *x: None
    
    
    # override: set force=0 always, as otherwise list gets cleared (bug)
    # Called on switching genre/category, or loading a genre for the first time.
    def load(self, category, force=False, y=None):
        log.UI("no reloading for file plugin")
        ChannelPlugin.load(self, self.current, force=0)


    # read dirs
    def scan_dirs(self):
        self.categories = []
    
        # add main directory
226
227
228
229
230
231
232

233
234
235
236

237
238
239
240
241
242
243
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251







+



-
+







            if self.streams.get(main_base):
                self.streams[main] = self.streams[main_base]


    # extract meta data
    def file_entry(self, fn, dir):
        # basic data
        url = ("%s/%s" % (dir, fn)).replace("\\", "/")
        meta = {
            "title": "",
            "filename": fn,
            "url": "file://" + dir + "/" + fn,
            "url": url,
            "genre": "",
            "album": "",
            "artist": "",
            "length": "n/a",
            "bitrate": "n/a",
#            "format": mime_fmt(fn[-3:]),
            "format": mime_fmt(fn[-(len(fn)-fn.rfind(".")-1):]),
270
271
272
273
274
275
276
277

278
279
280
281
278
279
280
281
282
283
284

285
286
287
288
289







-
+





    # same as init
    def update_categories(self):
        self.scan_dirs()

        
    # same as init
    def update_streams(self, cat, x=0):
    def update_streams(self, cat, *k, **kw):
        self.scan_dirs()
        return self.streams.get(os.path.basename(cat))


Modified st2.py from [41e5406dc6] to [83bfadb12a].

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
303
304
305
306
307
308
309


310
311
312
313
314
315
316







-
-







            log.UI("dblclick")
            url = self.channel().meta.get("url", "https://duckduckgo.com/?q=" + self.channel().module)
            action.browser(url)

    # Reload stream list in current channel-category
    def on_reload_clicked(self, widget=None, reload=1):
        log.UI("on_reload_clicked()", "reload=", reload, "current_channel=", self.current_channel, "c=", self.channels[self.current_channel], "cat=", self.channel().current)
        if self.current_channel == "file": # reload is removing entries without Station Title...
            reload=0
        self.thread(self._on_reload, self.channel(), reload)
    def _on_reload(self, channel, reload):
        self.channel().load(channel.current, force=reload)
        if reload:
            try: self.bookmarks.heuristic_update(self.current_channel, channel.category)
            except: pass