Adrian Sampson avatar Adrian Sampson committed 6debb3a

get and set flexattrs with hyphen keys

Here's another little experiment: to make flexattrs a little easier to use for
end users, you can now get and set them by using 'namespace-key' as the
argument to __getattr__ or __setattr__.

For example, try:
$ beet mod foo-bar=baz
$ beet ls -f '${foo-bar}'
baz
baz
baz
...

Comments (0)

Files changed (2)

                 setattr(self, key, values[key])
             except KeyError:
                 setattr(self, key, None)
-        self.flexattrs = flexattrs or {}
+
+        self.flexattrs = defaultdict(dict)
+        if flexattrs:
+            self.flexattrs.update(flexattrs)
 
     def _clear_dirty(self):
         self.dirty = {}
         """
         if key in ITEM_KEYS:
             return self.record.get(key)
+        elif '-' in key:
+            namespace, key = key.split('-', 1)
+            if namespace in self.flexattrs:
+                return self.flexattrs[namespace].get(key)
+            return None
         else:
             raise AttributeError(key + ' is not a valid item field')
 
                 self.dirty[key] = True
                 if key in ITEM_KEYS_WRITABLE:
                     self.mtime = 0 # Reset mtime on dirty.
+
+        elif '-' in key:
+            namespace, key = key.split('-', 1)
+            self.flexattrs[namespace][key] = value
+
         else:
             super(Item, self).__setattr__(key, value)
 
         if not mapping['albumartist']:
             mapping['albumartist'] = mapping['artist']
 
+        # Flexible attributes.
+        for namespace, attrs in self.flexattrs.items():
+            for key, value in attrs.items():
+                if sanitize:
+                    value = format_for_path(value, None, pathmod)
+                mapping['{}-{}'.format(namespace, key)] = value
+
         # Get values from plugins.
         for key, value in plugins.template_values(self).iteritems():
             if sanitize:

beets/ui/commands.py

     fsets = {}
     for mod in mods:
         key, value = mod.split('=', 1)
-        if key not in allowed_keys:
+        if key not in allowed_keys and '-' not in key:
             raise ui.UserError('"%s" is not a valid field' % key)
         fsets[key] = value
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.