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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [c9509eb384]

Overview
Comment:Filter `None` from extracted URLs. Fix save_playlist.export; copy.copy each row before overwriting/filling url. Implement specific `jamj` extractor (regex stumbled over playlist title).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c9509eb384772f6d3b50872351a5e5366693f5c9
User & Date: mario on 2015-05-05 19:47:57
Other Links: manifest | tags
Context
2015-05-05
20:08
Fix region_id default to enable v3 mostPopular query (YT stumbled over "UK"). check-in: 5a0c618e03 user: mario tags: trunk
19:47
Filter `None` from extracted URLs. Fix save_playlist.export; copy.copy each row before overwriting/filling url. Implement specific `jamj` extractor (regex stumbled over playlist title). check-in: c9509eb384 user: mario tags: trunk
17:25
Add .save() after reading in CSV list. check-in: 930e5fd7a5 user: mario tags: trunk
Changes

Modified action.py from [9f1cd78f49] to [75cdfd8027].

249
250
251
252
253
254
255

256
257
258
259
260
261
262
    if len(set([source, mime, probe])) > 1:
        log.WARN("Possible playlist format mismatch:", "listformat={}, http_mime={}, rx_probe={}, ext={}".format(source, mime, probe, ext))

    # Extract URLs from content
    for fmt in playlist_fmt_prio:
        if not urls and fmt in (source, mime, probe, ext, "raw"):
            urls = cnv.urls(fmt)

            log.DATA("conversion from:", source, " with extractor:", fmt, "got URLs=", urls)
            
    # Return original, or asis for srv targets
    if not urls:
        return [url]
    elif dest in ("srv", "href"):
        return urls







>







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    if len(set([source, mime, probe])) > 1:
        log.WARN("Possible playlist format mismatch:", "listformat={}, http_mime={}, rx_probe={}, ext={}".format(source, mime, probe, ext))

    # Extract URLs from content
    for fmt in playlist_fmt_prio:
        if not urls and fmt in (source, mime, probe, ext, "raw"):
            urls = cnv.urls(fmt)
            urls = filter(None, urls)
            log.DATA("conversion from:", source, " with extractor:", fmt, "got URLs=", urls)
            
    # Return original, or asis for srv targets
    if not urls:
        return [url]
    elif dest in ("srv", "href"):
        return urls
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
        "jspf": dict(
            split = r"(?s) \"track\":\s*\{ >",
            url   = r"(?s) \"location\" \s*:\s* \"(\w+://[^\"\s]+)\" ",
            unesc = "json",
        ),
        "jamj": dict(
            url   = r" (?x) \"audio\" \s*:\s* \"(\w+:\\?/\\?/[^\"\s]+)\" ",
            title = r" (?x) \"name\" \s*:\s* \"([^\"]+)\" ",
            unesc = "json",
        ),
        "json": dict(
            url   = r" (?x) \"(?:url|audio|stream)\" \s*:\s* \"(\w+:\\?/\\?/[^\"\s]+)\" ",
            title = r" (?x) \"(?:title|name|station)\" \s*:\s* \"([^\"]+)\" ",
            playing = r" (?x) \"(?:playing|current|description)\" \s*:\s* \"([^\"]+)\" ",
            homepage= r" (?x) \"(?:homepage|website|info)\" \s*:\s* \"([^\"]+)\" ",







|







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
        "jspf": dict(
            split = r"(?s) \"track\":\s*\{ >",
            url   = r"(?s) \"location\" \s*:\s* \"(\w+://[^\"\s]+)\" ",
            unesc = "json",
        ),
        "jamj": dict(
            url   = r" (?x) \"audio\" \s*:\s* \"(\w+:\\?/\\?/[^\"\s]+)\" ",
           #title = r" (?x) \"name\" \s*:\s* \"([^\"]+)\" ",
            unesc = "json",
        ),
        "json": dict(
            url   = r" (?x) \"(?:url|audio|stream)\" \s*:\s* \"(\w+:\\?/\\?/[^\"\s]+)\" ",
            title = r" (?x) \"(?:title|name|station)\" \s*:\s* \"([^\"]+)\" ",
            playing = r" (?x) \"(?:playing|current|description)\" \s*:\s* \"([^\"]+)\" ",
            homepage= r" (?x) \"(?:homepage|website|info)\" \s*:\s* \"([^\"]+)\" ",
494
495
496
497
498
499
500














501
502
503
504
505
506
507
            if not num in rows:
                rows[num] = {}
            field = fieldmap.get(field.lower())
            if field and len(value):
                rows[num][field] = value.strip()
        return [rows[str(i)] for i in sorted(map(int, rows.keys()))]
















    # Add placeholder fields to extracted row
    def mkrow(self, row, title=None):
        url = row.get("url", "")
        comb = {
            "title": row.get("title") or re.sub("\.\w+$", "", os.path.basename(self.fn)),
            "playing": "",







>
>
>
>
>
>
>
>
>
>
>
>
>
>







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
            if not num in rows:
                rows[num] = {}
            field = fieldmap.get(field.lower())
            if field and len(value):
                rows[num][field] = value.strip()
        return [rows[str(i)] for i in sorted(map(int, rows.keys()))]


    # Jamendo JAMJAMJSON playlists
    def jamj(self):
        rows = []
        for result in json.loads(self.src)["results"]:
            for track in result["tracks"]:
                rows.append(dict(
                    title = track["name"],
                    url = track["audio"],
                    playing = track.get("artist_name"),
                    img = track.get("image"),
                ))
        return rows


    # Add placeholder fields to extracted row
    def mkrow(self, row, title=None):
        url = row.get("url", "")
        comb = {
            "title": row.get("title") or re.sub("\.\w+$", "", os.path.basename(self.fn)),
            "playing": "",
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
    # Used by playlist_convert(), to transform a list of extracted URLs
    # into a local .pls/.m3u collection again. Therefore injects the
    # `title` back into each of the URL rows / or uses row{} template.
    def export(self, urls=[], row={}, dest="pls", title=None):
        row["title"] = row.get("title", title or "unnamed stream")
        rows = []
        for url in urls:

            row.update(url=url)
            rows.append(row)
        return self.store(rows, dest)


    # Export a playlist from rows{}
    def store(self, rows=None, dest="pls"):
    
        # can be just a single entry







>
|
|







577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
    # Used by playlist_convert(), to transform a list of extracted URLs
    # into a local .pls/.m3u collection again. Therefore injects the
    # `title` back into each of the URL rows / or uses row{} template.
    def export(self, urls=[], row={}, dest="pls", title=None):
        row["title"] = row.get("title", title or "unnamed stream")
        rows = []
        for url in urls:
            if url:
                row.update(url=url)
                rows.append(copy.copy(row))
        return self.store(rows, dest)


    # Export a playlist from rows{}
    def store(self, rows=None, dest="pls"):
    
        # can be just a single entry