CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-beets

A comprehensive music library management system and command-line application for organizing and maintaining digital music collections

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

query-system.mddocs/

Query System

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.

Capabilities

Query Parsing Functions

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
    """

Base Query Classes

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
        """

String Query Types

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
        """

Numeric Query Types

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')
        """

Boolean Logic Queries

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
        """

Special Query Types

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
        """

Query Language Syntax

Basic Field Matching

# 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 Patterns

# 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"

Numeric Comparisons

# 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

Date Queries

# 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

Boolean Logic

# 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 Queries

# 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 directory

Query Usage Examples

Library Queries

from 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)

Programmatic Query Building

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)

Custom Query Types

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'] = GenreQuery

Sort Operations

class 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
        """

Sort Syntax

# 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 desc

Error Handling

class InvalidQueryError(Exception):
    """Raised when query string cannot be parsed."""

class InvalidSortError(Exception):
    """Raised when sort specification is invalid."""

Common query errors:

  • Invalid field names
  • Malformed regular expressions
  • Invalid date formats
  • Syntax errors in complex queries

Install with Tessl CLI

npx tessl i tessl/pypi-beets

docs

configuration.md

import-autotag.md

index.md

library-management.md

plugin-system.md

query-system.md

user-interface.md

utilities-templates.md

tile.json