A comprehensive music library management system and command-line application for organizing and maintaining digital music collections
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Sophisticated query language and parsing system for filtering library content with support for field matching, regular expressions, numeric comparisons, and boolean logic. The query system enables powerful library searches and filtering.
Functions for parsing query strings into Query objects that can be executed against the database.
def query_from_strings(strings: List[str], model_cls: Type) -> Query:
"""
Parse a list of query strings into a single Query object.
Parameters:
- strings: List of query string components
- model_cls: Item or Album class for context
Returns:
Combined Query object for database execution
"""
def parse_sorted_query(query_string: str, model_cls: Type) -> Tuple[Query, Sort]:
"""
Parse a query string that may include sort specifications.
Parameters:
- query_string: Complete query string with optional sort
- model_cls: Item or Album class for context
Returns:
Tuple of (Query object, Sort object)
"""
def parse_query_part(part: str, model_cls: Type) -> Query:
"""
Parse a single query component into a Query object.
Parameters:
- part: Single query string component
- model_cls: Item or Album class for context
Returns:
Query object for the component
"""Core query interface and base implementations for different query types.
class Query:
"""Base class for all query types."""
def match(self, item: Union[Item, Album]) -> bool:
"""
Test whether this query matches an item or album.
Parameters:
- item: Item or Album object to test
Returns:
True if the query matches the object
"""
def clause(self) -> Tuple[str, List[Any]]:
"""
Generate SQL WHERE clause for database execution.
Returns:
Tuple of (SQL string, parameter list)
"""
class FieldQuery(Query):
"""Base class for queries that operate on specific fields."""
def __init__(self, field: str, pattern: Any, fast: bool = True):
"""
Initialize field-based query.
Parameters:
- field: Name of the field to query
- pattern: Pattern or value to match against
- fast: Whether to use fast database operations when possible
"""Query types for matching text fields with various string comparison methods.
class StringQuery(FieldQuery):
"""Query for exact or partial string matches."""
def __init__(self, field: str, pattern: str, fast: bool = True):
"""
Create string matching query.
Parameters:
- field: Field name to search
- pattern: String pattern to match (supports wildcards)
- fast: Use database string operations when possible
"""
class SubstringQuery(StringQuery):
"""Query for substring matches (case-insensitive)."""
def __init__(self, field: str, pattern: str):
"""
Create substring matching query.
Parameters:
- field: Field name to search
- pattern: Substring to find within field values
"""
class RegexpQuery(FieldQuery):
"""Query using regular expressions for pattern matching."""
def __init__(self, field: str, pattern: str):
"""
Create regular expression query.
Parameters:
- field: Field name to search
- pattern: Regular expression pattern
"""Query types for numeric comparisons and range operations.
class NumericQuery(FieldQuery):
"""Query for numeric field comparisons."""
def __init__(self, field: str, point: float, interval: float = 0):
"""
Create numeric comparison query.
Parameters:
- field: Numeric field name
- point: Target value for comparison
- interval: Range around target (0 for exact match)
"""
class DateQuery(FieldQuery):
"""Query for date/time field comparisons."""
def __init__(self, field: str, date: str, precision: str = 'day'):
"""
Create date comparison query.
Parameters:
- field: Date field name (year, month, day, added, mtime)
- date: Date string in various formats
- precision: Precision level ('year', 'month', 'day')
"""
class DurationQuery(FieldQuery):
"""Query for duration/length field comparisons."""
def __init__(self, field: str, duration: str):
"""
Create duration comparison query.
Parameters:
- field: Duration field name (typically 'length')
- duration: Duration string (e.g., '3:30', '210s')
"""Query types for combining multiple queries with logical operations.
class AndQuery(Query):
"""Query that matches when ALL subqueries match."""
def __init__(self, subqueries: List[Query]):
"""
Create AND logic query.
Parameters:
- subqueries: List of Query objects that must all match
"""
class OrQuery(Query):
"""Query that matches when ANY subquery matches."""
def __init__(self, subqueries: List[Query]):
"""
Create OR logic query.
Parameters:
- subqueries: List of Query objects, any of which can match
"""
class NotQuery(Query):
"""Query that matches when subquery does NOT match."""
def __init__(self, subquery: Query):
"""
Create NOT logic query.
Parameters:
- subquery: Query object to negate
"""Additional query types for specific use cases and edge conditions.
class TrueQuery(Query):
"""Query that always matches (returns all items)."""
def match(self, item: Any) -> bool:
return True
class FalseQuery(Query):
"""Query that never matches (returns no items)."""
def match(self, item: Any) -> bool:
return False
class PathQuery(FieldQuery):
"""Query for filesystem path matching with platform-aware comparisons."""
def __init__(self, field: str, pattern: str):
"""
Create path matching query.
Parameters:
- field: Path field name (typically 'path')
- pattern: Path pattern with filesystem-appropriate separators
"""
class CollectionQuery(Query):
"""Query for matching items within specific collections or playlists."""
def __init__(self, collection_name: str):
"""
Create collection membership query.
Parameters:
- collection_name: Name of collection to match against
"""# Field equals value
items = lib.items('artist:Beatles')
items = lib.items('year:1969')
# Field contains substring
items = lib.items('title:love')
# Case-insensitive matching is default
items = lib.items('artist:beatles') # Matches "Beatles"# Wildcards (* and ?)
items = lib.items('artist:*Beatles*') # Contains "Beatles"
items = lib.items('title:Hey?') # "Hey" followed by one char
# Regular expressions (prefix with ~)
items = lib.items('artist:~(Beatles|Rolling Stones)')
items = lib.items('title:~^Love') # Starts with "Love"# Exact values
items = lib.items('year:1969')
items = lib.items('track:5')
# Ranges (inclusive)
items = lib.items('year:1960..1970') # 1960 to 1970
items = lib.items('length:180..240') # 3-4 minutes
# Comparisons
items = lib.items('year:..1970') # Up to 1970
items = lib.items('year:1980..') # 1980 and later# Specific dates
items = lib.items('added:2024-01-01')
items = lib.items('mtime:2024-01-01..2024-01-31')
# Relative dates
items = lib.items('added:1d..') # Added in last day
items = lib.items('added:1w..') # Added in last week
items = lib.items('added:1m..') # Added in last month# AND (default when multiple terms)
items = lib.items('artist:Beatles year:1969')
# OR (comma-separated)
items = lib.items('artist:Beatles,Stones')
# NOT (prefix with -)
items = lib.items('artist:Beatles -album:Anthology')
# Grouping with parentheses
items = lib.items('(artist:Beatles year:1960..1970) genre:Rock')# Path contains
items = lib.items('path:/music/rock/')
# Path patterns
items = lib.items('path:*.flac') # FLAC files only
items = lib.items('path:~/Music/*') # In Music directoryfrom beets.library import Library
from beets.dbcore.queryparse import query_from_strings, parse_sorted_query
lib = Library('/path/to/library.db', '/music')
# Simple queries
rock_items = lib.items('genre:Rock')
recent_albums = lib.albums('added:2024..')
# Complex queries
query_parts = ['artist:Beatles', 'year:1960..1970', '-album:Anthology']
beatles_60s = lib.items(' '.join(query_parts))
# Sorted queries
query, sort = parse_sorted_query('artist:Beatles year+', lib.Item)
sorted_items = lib.items(query, sort)from beets.dbcore.query import AndQuery, StringQuery, NumericQuery
# Build queries programmatically
artist_query = StringQuery('artist', 'Beatles')
year_query = NumericQuery('year', 1969)
combined = AndQuery([artist_query, year_query])
# Use with library
items = lib.items(combined)from beets.dbcore.query import FieldQuery
class GenreQuery(FieldQuery):
"""Custom query for genre matching with normalization."""
def __init__(self, field: str, genre: str):
# Normalize genre names
normalized = genre.lower().replace('-', ' ')
super().__init__(field, normalized)
def match(self, item):
item_genre = item.genre.lower().replace('-', ' ')
return self.pattern in item_genre
# Register custom query type
from beets.dbcore.queryparse import query_classes
query_classes['genre'] = GenreQueryclass Sort:
"""Represents sorting specification for query results."""
def __init__(self, field: str, ascending: bool = True):
"""
Create sort specification.
Parameters:
- field: Field name to sort by
- ascending: True for ascending, False for descending
"""
class MultipleSort(Sort):
"""Sort by multiple fields in priority order."""
def __init__(self, sorts: List[Sort]):
"""
Create multi-field sort.
Parameters:
- sorts: List of Sort objects in priority order
"""# Single field sorts
items = lib.items('artist:Beatles', sort='year+') # Ascending by year
items = lib.items('artist:Beatles', sort='year-') # Descending by year
# Multiple field sorts
items = lib.items('genre:Rock', sort='artist+ year-') # Artist asc, year descclass InvalidQueryError(Exception):
"""Raised when query string cannot be parsed."""
class InvalidSortError(Exception):
"""Raised when sort specification is invalid."""Common query errors:
Install with Tessl CLI
npx tessl i tessl/pypi-beets