def random_item(lib, config, opts, args): query = decargs(args) path = opts.path fmt = opts.format if fmt is None: # If no specific template is supplied, use a default if opts.album: fmt = u'$albumartist - $album' else: fmt = u'$artist - $album - $title' template = Template(fmt) if opts.album: objs = list(lib.albums(query=query)) else: objs = list(lib.items(query=query)) number = min(len(objs), opts.number) objs = random.sample(objs, number) if opts.album: for album in objs: if path: print_(album.item_dir()) else: print_(template.substitute(album._record)) else: for item in objs: if path: print_(item.path) else: print_(template.substitute(item.record))
def list_items(lib, query, album, path, fmt): """Print out items in lib matching query. If album, then search for albums instead of single items. If path, print the matched objects' paths instead of human-readable information about them. """ if fmt is None: # If no specific template is supplied, use a default. if album: fmt = u'$albumartist - $album' else: fmt = u'$artist - $album - $title' template = Template(fmt) if album: for album in lib.albums(query): if path: print_(album.item_dir()) elif fmt is not None: print_(template.substitute(album._record)) else: for item in lib.items(query): if path: print_(item.path) elif fmt is not None: print_(template.substitute(item.record))
def _destination(self, filename, mapping): '''Returns a destination path a file should be moved to. The filename is unique to ensure files aren't overwritten. This also checks the config for path formats based on file extension allowing the use of beets' template functions. If no path formats are found for the file extension the original filename is used with the album path. - ripped from beets/library.py ''' file_ext = os.path.splitext(filename)[1] for query, path_format in self.path_formats: query_ext = '.' + query[4:] if query_ext == file_ext.decode('utf8'): break else: # No query matched; use original filename file_path = os.path.join(mapping['albumpath'], beets.util.displayable_path(filename)) return file_path if isinstance(path_format, Template): subpath_tmpl = path_format else: subpath_tmpl = Template(path_format) # Get template funcs and evaluate against mapping funcs = DefaultTemplateFunctions().functions() file_path = subpath_tmpl.substitute(mapping, funcs) + file_ext.decode('utf8') # Sanitize filename filename = beets.util.sanitize_path(os.path.basename(file_path)) dirname = os.path.dirname(file_path) file_path = os.path.join(dirname, filename) return file_path
def _destination(self, filename, mapping): '''Returns a destination path a file should be moved to. The filename is unique to ensure files aren't overwritten. This also checks the config for path formats based on file extension allowing the use of beets' template functions. If no path formats are found for the file extension the original filename is used with the album path. - ripped from beets/library.py ''' file_ext = os.path.splitext(filename)[1] for query, path_format in self.path_formats: query_ext = '.' + query[4:] if query_ext == file_ext: break else: # No query matched; use original filename file_path = os.path.join(mapping['albumpath'], beets.util.displayable_path(filename)) return file_path if isinstance(path_format, Template): subpath_tmpl = path_format else: subpath_tmpl = Template(path_format) # Get template funcs and evaluate against mapping funcs = DefaultTemplateFunctions().functions() file_path = subpath_tmpl.substitute(mapping, funcs) + file_ext # Sanitize filename filename = beets.util.sanitize_path(os.path.basename(file_path)) dirname = os.path.dirname(file_path) file_path = os.path.join(dirname, filename) return file_path
def _destination(self, filename, mapping): '''Returns a destination path a file should be moved to. The filename is unique to ensure files aren't overwritten. This also checks the config for path formats based on file extension allowing the use of beets' template functions. If no path formats are found for the file extension the original filename is used with the album path. - ripped from beets/library.py ''' file_ext = os.path.splitext(filename)[1] for query, path_format in self.path_formats: query_ext = '.' + query[4:] if query_ext == file_ext: break else: # No query matched; use original filename if self.remaining_folder!=[]: #remaining_folder = self.remaining_folder.replace('/','')+'/' # Make sure there is a trailing slash remaining_folder = self.remaining_folder+'/' # Make sure there is a trailing slash file_path = os.path.join(mapping['albumpath'],remaining_folder, beets.util.displayable_path(filename)) else: file_path = os.path.join(mapping['albumpath'], beets.util.displayable_path(filename)) return file_path if isinstance(path_format, Template): subpath_tmpl = path_format else: subpath_tmpl = Template(path_format) # Get template funcs and evaluate against mapping funcs = DefaultTemplateFunctions().functions() file_path = subpath_tmpl.substitute(mapping, funcs) + file_ext return file_path
def evaluate_template(self, template, for_path=False): """Evaluate a template (a string or a `Template` object) using the object's fields. If `for_path` is true, then no new path separators will be added to the template. """ # Perform substitution. if isinstance(template, basestring): template = Template(template) return template.substitute(self.formatted(for_path), self._template_funcs())
def evaluate_template(self, template, for_path=False): """Evaluate a template (a string or a `Template` object) using the object's fields. If `for_path` is true, then no new path separators will be added to the template. """ # Perform substitution. if isinstance(template, basestring): template = Template(template) return template.substitute(self.formatted(for_path), self._template_funcs())
def evaluate_template(self, template, for_path=False): """Evaluate a template (a string or a `Template` object) using the object's fields. If `for_path` is true, then no new path separators will be added to the template. """ # Build value mapping. mapping = self._formatted_mapping(for_path) # Get template functions. funcs = self._template_funcs() # Perform substitution. if isinstance(template, basestring): template = Template(template) return template.substitute(mapping, funcs)
def evaluate_template(self, template, for_path=False): """Evaluate a template (a string or a `Template` object) using the object's fields. If `for_path` is true, then no new path separators will be added to the template. """ # Build value mapping. mapping = self._formatted_mapping(for_path) # Get template functions. funcs = self._template_funcs() # Perform substitution. if isinstance(template, basestring): template = Template(template) return template.substitute(mapping, funcs)
def destination(self, item, pathmod=None, in_album=False, fragment=False, basedir=None): """Returns the path in the library directory designated for item item (i.e., where the file ought to be). in_album forces the item to be treated as part of an album. fragment makes this method return just the path fragment underneath the root library directory; the path is also returned as Unicode instead of encoded as a bytestring. basedir can override the library's base directory for the destination. """ pathmod = pathmod or os.path # Use a path format based on the album type, if available. if not item.album_id and not in_album: # Singleton track. Never use the "album" formats. if 'singleton' in self.path_formats: path_format = self.path_formats['singleton'] else: path_format = self.path_formats['default'] elif item.albumtype and item.albumtype in self.path_formats: path_format = self.path_formats[item.albumtype] elif item.comp and 'comp' in self.path_formats: path_format = self.path_formats['comp'] else: path_format = self.path_formats['default'] subpath_tmpl = Template(path_format) # Get the item's Album if it has one. album = self.get_album(item) # Build the mapping for substitution in the path template, # beginning with the values from the database. mapping = {} for key in ITEM_KEYS_META: # Get the values from either the item or its album. if key in ALBUM_KEYS_ITEM and album is not None: # From album. value = getattr(album, key) else: # From Item. value = getattr(item, key) mapping[key] = util.sanitize_for_path(value, pathmod, key) # Use the album artist if the track artist is not set and # vice-versa. if not mapping['artist']: mapping['artist'] = mapping['albumartist'] if not mapping['albumartist']: mapping['albumartist'] = mapping['artist'] # Perform substitution. subpath = subpath_tmpl.substitute(mapping, TEMPLATE_FUNCTIONS) # Encode for the filesystem, dropping unencodable characters. if isinstance(subpath, unicode) and not fragment: encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() subpath = subpath.encode(encoding, 'replace') # Truncate components and remove forbidden characters. subpath = util.sanitize_path(subpath) # Preserve extension. _, extension = pathmod.splitext(item.path) subpath += extension if fragment: return subpath else: basedir = basedir or self.directory return normpath(os.path.join(basedir, subpath))
def destination(self, item, pathmod=None, in_album=False, fragment=False, basedir=None): """Returns the path in the library directory designated for item item (i.e., where the file ought to be). in_album forces the item to be treated as part of an album. fragment makes this method return just the path fragment underneath the root library directory; the path is also returned as Unicode instead of encoded as a bytestring. basedir can override the library's base directory for the destination. """ pathmod = pathmod or os.path # Use a path format based on a query, falling back on the # default. for query, path_format in self.path_formats: if query == PF_KEY_DEFAULT: continue query = AndQuery.from_string(query) if in_album: # If we're treating this item as a member of the item, # hack the query so that singleton queries always # observe the item to be non-singleton. for i, subquery in enumerate(query): if isinstance(subquery, SingletonQuery): query[i] = FalseQuery() if subquery.sense \ else TrueQuery() if query.match(item): # The query matches the item! Use the corresponding path # format. break else: # No query matched; fall back to default. for query, path_format in self.path_formats: if query == PF_KEY_DEFAULT: break else: assert False, "no default path format" subpath_tmpl = Template(path_format) # Get the item's Album if it has one. album = self.get_album(item) # Build the mapping for substitution in the path template, # beginning with the values from the database. mapping = {} for key in ITEM_KEYS_META: # Get the values from either the item or its album. if key in ALBUM_KEYS_ITEM and album is not None: # From album. value = getattr(album, key) else: # From Item. value = getattr(item, key) mapping[key] = util.sanitize_for_path(value, pathmod, key) # Use the album artist if the track artist is not set and # vice-versa. if not mapping['artist']: mapping['artist'] = mapping['albumartist'] if not mapping['albumartist']: mapping['albumartist'] = mapping['artist'] # Perform substitution. mapping.update(plugins.template_values(item)) funcs = dict(TEMPLATE_FUNCTIONS) funcs.update(plugins.template_funcs()) subpath = subpath_tmpl.substitute(mapping, funcs) # Encode for the filesystem, dropping unencodable characters. if isinstance(subpath, unicode) and not fragment: encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() subpath = subpath.encode(encoding, 'replace') # Truncate components and remove forbidden characters. subpath = util.sanitize_path(subpath, pathmod, self.replacements) # Preserve extension. _, extension = pathmod.splitext(item.path) subpath += extension if fragment: return subpath else: basedir = basedir or self.directory return normpath(os.path.join(basedir, subpath))
def destination(self, item, pathmod=None, in_album=False, fragment=False, basedir=None): """Returns the path in the library directory designated for item item (i.e., where the file ought to be). in_album forces the item to be treated as part of an album. fragment makes this method return just the path fragment underneath the root library directory; the path is also returned as Unicode instead of encoded as a bytestring. basedir can override the library's base directory for the destination. """ pathmod = pathmod or os.path # Use a path format based on a query, falling back on the # default. for query, path_format in self.path_formats: if query == PF_KEY_DEFAULT: continue query = AndQuery.from_string(query) if in_album: # If we're treating this item as a member of the item, # hack the query so that singleton queries always # observe the item to be non-singleton. for i, subquery in enumerate(query): if isinstance(subquery, SingletonQuery): query[i] = FalseQuery() if subquery.sense \ else TrueQuery() if query.match(item): # The query matches the item! Use the corresponding path # format. break else: # No query matched; fall back to default. for query, path_format in self.path_formats: if query == PF_KEY_DEFAULT: break else: assert False, "no default path format" subpath_tmpl = Template(path_format) # Get the item's Album if it has one. album = self.get_album(item) # Build the mapping for substitution in the path template, # beginning with the values from the database. mapping = {} for key in ITEM_KEYS_META: # Get the values from either the item or its album. if key in ALBUM_KEYS_ITEM and album is not None: # From album. value = getattr(album, key) else: # From Item. value = getattr(item, key) mapping[key] = util.sanitize_for_path(value, pathmod, key) # Use the album artist if the track artist is not set and # vice-versa. if not mapping['artist']: mapping['artist'] = mapping['albumartist'] if not mapping['albumartist']: mapping['albumartist'] = mapping['artist'] # Perform substitution. mapping.update(plugins.template_values(item)) funcs = dict(TEMPLATE_FUNCTIONS) funcs.update(plugins.template_funcs()) subpath = subpath_tmpl.substitute(mapping, funcs) # Encode for the filesystem, dropping unencodable characters. if isinstance(subpath, unicode) and not fragment: encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() subpath = subpath.encode(encoding, 'replace') # Truncate components and remove forbidden characters. subpath = util.sanitize_path(subpath, pathmod, self.replacements) # Preserve extension. _, extension = pathmod.splitext(item.path) subpath += extension if fragment: return subpath else: basedir = basedir or self.directory return normpath(os.path.join(basedir, subpath))
def destination(self, item, pathmod=None, in_album=False, fragment=False, basedir=None): """Returns the path in the library directory designated for item item (i.e., where the file ought to be). in_album forces the item to be treated as part of an album. fragment makes this method return just the path fragment underneath the root library directory; the path is also returned as Unicode instead of encoded as a bytestring. basedir can override the library's base directory for the destination. """ pathmod = pathmod or os.path # Use a path format based on the album type, if available. if not item.album_id and not in_album: # Singleton track. Never use the "album" formats. if 'singleton' in self.path_formats: path_format = self.path_formats['singleton'] else: path_format = self.path_formats['default'] elif item.albumtype and item.albumtype in self.path_formats: path_format = self.path_formats[item.albumtype] elif item.comp and 'comp' in self.path_formats: path_format = self.path_formats['comp'] else: path_format = self.path_formats['default'] subpath_tmpl = Template(path_format) # Get the item's Album if it has one. album = self.get_album(item) # Build the mapping for substitution in the path template, # beginning with the values from the database. mapping = {} for key in ITEM_KEYS_META: # Get the values from either the item or its album. if key in ALBUM_KEYS_ITEM and album is not None: # From album. value = getattr(album, key) else: # From Item. value = getattr(item, key) mapping[key] = util.sanitize_for_path(value, pathmod, key) # Use the album artist if the track artist is not set and # vice-versa. if not mapping['artist']: mapping['artist'] = mapping['albumartist'] if not mapping['albumartist']: mapping['albumartist'] = mapping['artist'] # Perform substitution. subpath = subpath_tmpl.substitute(mapping, TEMPLATE_FUNCTIONS) # Encode for the filesystem, dropping unencodable characters. if isinstance(subpath, unicode) and not fragment: encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() subpath = subpath.encode(encoding, 'replace') # Truncate components and remove forbidden characters. subpath = util.sanitize_path(subpath) # Preserve extension. _, extension = pathmod.splitext(item.path) subpath += extension if fragment: return subpath else: basedir = basedir or self.directory return normpath(os.path.join(basedir, subpath))