def _dict_for(self, song): d = {} for tag in SAVED_METATAGS + song.realkeys(): val = song(tag) if val: if isinstance(val, basestring): if tag in QUOTED_TAGS: val = util.qdecode(val) else: val = util.fsdecode(val) if not tag in SINGLETON_TAGS: val = val.split("\n") d[tag] = val for tag, default in DEFAULTS.items(): if not tag in song: song[tag] = default d["~path"] = d["~filename"].split(os.path.sep) # CouchDB doesn't like apostrophes in keys for some reason... d["_id"] = _id(song.key) return d
def __call__(self, key, default=u"", connector=" - "): """Return a key, synthesizing it if necessary. A default value may be given (like dict.get); the default default is an empty unicode string (even if the tag is numeric).""" if key[:1] == "~": key = key[1:] if key == "#track": try: return int(self["tracknumber"].split("/")[0]) except (ValueError, TypeError, KeyError): return default elif key == "#disc": try: return int(self["discnumber"].split("/")[0]) except (ValueError, TypeError, KeyError): return default elif key == "people": join = "\n".join people = filter(None, map(self.__call__, PEOPLE)) people = join(people).split("\n") index = people.index return join([person for (i, person) in enumerate(people) if index(person) == i]) elif key == "peoplesort": join = "\n".join people = filter(None, map(self.__call__, PEOPLE_SORT)) people = join(people).split("\n") index = people.index return (join([person for (i, person) in enumerate(people) if index(person) == i]) or self("~people", default, connector)) elif key == "performers": values = [] for key in self.realkeys(): if key.startswith("performer:"): role = key.split(":", 1)[1] for value in self.list(key): values.append("%s (%s)" % (value, role)) values.extend(self.list("performer")) return "\n".join(values) elif key == "performerssort": values = [] for key in self.realkeys(): if key.startswith("performersort:"): role = key.split(":", 1)[1] for value in self.list(key): values.append("%s (%s)" % (value, role)) values.extend(self.list("performersort")) return ("\n".join(values) or self("~performers", default, connector)) elif key == "basename": return os.path.basename(self["~filename"]) or self["~filename"] elif key == "dirname": return os.path.dirname(self["~filename"]) or self["~filename"] elif key == "uri": try: return self["~uri"] except KeyError: return "file://" + pathname2url(self["~filename"]) elif key == "format": return self.get("~format", self.format) elif key == "year": return self.get("date", default)[:4] elif key == "#year": try: return int(self.get("date", default)[:4]) except (ValueError, TypeError, KeyError): return default elif key == "#tracks": try: return int(self["tracknumber"].split("/")[1]) except (ValueError, IndexError, TypeError, KeyError): return default elif key == "#discs": try: return int(self["discnumber"].split("/")[1]) except (ValueError, IndexError, TypeError, KeyError): return default elif key[:1] == "#" and "~" + key not in self: try: return int(self[key[1:]]) except (ValueError, TypeError, KeyError): return default else: return dict.get(self, "~" + key, default) elif key == "title": title = dict.get(self, "title") if title is None: basename = self("~basename") basename = util.fsdecode(basename) return "%s [%s]" % (basename, "Unknown") else: return title elif key in SORT_TO_TAG: try: return self[key] except KeyError: key = SORT_TO_TAG[key] return dict.get(self, key, default)