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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [ea30a91e8d]

Overview
Comment:Allow plugin # config: bags only with <> or {} as delimiters, to support markup description/label.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ea30a91e8db71f023a570dbd9172a927f610b501
User & Date: mario on 2016-10-22 18:58:26
Other Links: manifest | tags
Context
2016-10-22
18:58
Shorten "house-mixes" title. check-in: dd4aa1e8ec user: mario tags: trunk
18:58
Allow plugin # config: bags only with <> or {} as delimiters, to support markup description/label. check-in: ea30a91e8d user: mario tags: trunk
2016-10-18
22:11
Move action/playback handlers to contrib/cmdline/ check-in: 05817e12db user: mario tags: trunk
Changes

Modified channels/configwin.py from [7969234304] to [75725508ad].

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
        doc = meta.get("doc", "").strip()
        if ver < 3:
            doc = re.sub("(?<=\S) *\n(?! *\n)", " ", doc)
        return doc

    # Put config widgets into channels/features configwin notebooks
    def add_channels(self, id=None, w=None, label=None, color=None, image=None, align=20):
        self.plugin_options.pack_start(uikit.wrap(self.widgets, id, w, label, color, image, align))

    # Separate tab for non-channel plugins
    def add_features(self, id=None, w=None, label=None, color=None, image=None, align=20):
        self.feature_options.pack_start(uikit.wrap(self.widgets, id, w, label, color, image, align))


    # save config
    def save(self, widget):
        self.save_config(conf.__dict__, "config_")
        self.save_config(conf.plugins, "config_plugins_")
        [callback() for callback in self.hooks["config_save"]]
        conf.save(nice=1)
        self.hide()








|



|










190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
        doc = meta.get("doc", "").strip()
        if ver < 3:
            doc = re.sub("(?<=\S) *\n(?! *\n)", " ", doc)
        return doc

    # Put config widgets into channels/features configwin notebooks
    def add_channels(self, id=None, w=None, label=None, color=None, image=None, align=20):
        self.plugin_options.pack_start(uikit.wrap(self.widgets, id, w, label, color, image, align, label_markup=1))

    # Separate tab for non-channel plugins
    def add_features(self, id=None, w=None, label=None, color=None, image=None, align=20):
        self.feature_options.pack_start(uikit.wrap(self.widgets, id, w, label, color, image, align, label_markup=1))


    # save config
    def save(self, widget):
        self.save_config(conf.__dict__, "config_")
        self.save_config(conf.plugins, "config_plugins_")
        [callback() for callback in self.hooks["config_save"]]
        conf.save(nice=1)
        self.hide()

Modified pluginconf.py from [9a5f974003] to [3b562696a0].

268
269
270
271
272
273
274

275
276
277
278
279
280
281
#   { name=option2, type=boolean, $value=1, etc. }
#
# Stubs out name, value, type, description if absent.
#
def plugin_meta_config(str):
    config = []
    for entry in rx.config.findall(str):

        opt = {
            "type": None,
            "name": None,
            "description": "",
            "value": None
        }
        for field in rx.options.findall(entry):







>







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#   { name=option2, type=boolean, $value=1, etc. }
#
# Stubs out name, value, type, description if absent.
#
def plugin_meta_config(str):
    config = []
    for entry in rx.config.findall(str):
        entry = entry[0] or entry[1]
        opt = {
            "type": None,
            "name": None,
            "description": "",
            "value": None
        }
        for field in rx.options.findall(entry):
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
class rx:
    comment = re.compile(r"""(^ {0,4}#.*\n)+""", re.M)
    hash = re.compile(r"""(^ {0,4}# *)""", re.M)
    keyval = re.compile(r"""
        ^([\w-]+):(.*$(?:\n(?![\w-]+:).+$)*)      # plain key:value lines
    """, re.M | re.X)
    config = re.compile(r"""
        [\{\<] (.+?) [\}\>]                    # JSOL/YAML scheme {...} dicts
    """, re.X)
    options = re.compile(r"""
        ["':$]?   (\w*)  ["']?                 # key or ":key" or '$key'
        \s* [:=] \s*                           # "=" or ":"
     (?:  "  ([^"]*)  "
       |  '  ([^']*)  '                        #  "quoted" or 'singl' values
       |     ([^,]*)                           #  or unquoted literals







|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
class rx:
    comment = re.compile(r"""(^ {0,4}#.*\n)+""", re.M)
    hash = re.compile(r"""(^ {0,4}# *)""", re.M)
    keyval = re.compile(r"""
        ^([\w-]+):(.*$(?:\n(?![\w-]+:).+$)*)      # plain key:value lines
    """, re.M | re.X)
    config = re.compile(r"""
        \{ (.+?) \} | \< (.+?) \>              # JSOL/YAML scheme {...} dicts
    """, re.X)
    options = re.compile(r"""
        ["':$]?   (\w*)  ["']?                 # key or ":key" or '$key'
        \s* [:=] \s*                           # "=" or ":"
     (?:  "  ([^"]*)  "
       |  '  ([^']*)  '                        #  "quoted" or 'singl' values
       |     ([^,]*)                           #  or unquoted literals