Add search command

This commit is contained in:
Joshua Boniface 2023-04-07 02:09:41 -04:00
parent 95c6a6bac4
commit 083ff1884b
2 changed files with 78 additions and 8 deletions

View File

@ -103,9 +103,16 @@ If a song ends up with no `dl_links` during scanning, for instance because they
"download sites", it will not be included in the database. Thus, the final number of songs in your database is
guaranteed to be smaller than the total number listed on the C3DB website.
## Downloading
## Searching & Downloading
Once a database has been built, you can start downloading songs.
Once a database has been built, you can start searching for downloading songs.
To search for songs, use the `search` command. This command takes `--filter` arguments in order to show what
song(s) would be downloaded by a given filter, without actually triggering the download. Once you have a valid
filter from a search, you can use it to download.
To download songs, use the `download` command. See the following sections for more details on the specifics of
the filters and output formatting of the `download` command.
By default, when downloading a given song, all possible download links (`dl_links`) will be downloaded; this
can be limited by using the `-i`/`--download-id` and `-d`/`--download-descr` options to pick and choose specific
@ -131,15 +138,18 @@ genres, artists, authors, etc. to make your custom song packs.
Note that we *cannot* filter - mostly for parsing difficulty reasons - by intrument type or difficulty, by song
length, or by any other information not mentioned above.
Filtering is always done during the download stage; the JSON database will always contain all possible entries.
Filtering is always done during the search/download stage; the JSON database will always contain all possible entries.
To use filters, append one or more `--filter` options to your `c3dbdl download` command. A filter option begins
with the literal `--filter`, followed by the category (e.g. `genre` or `artist`), then finally the text to filter
on, for instance `Rock` or `Santana` or `2012`. The text must be quoted if it contains whitespace.
To use filters, append one or more `--filter` options to your `c3dbdl download` or `search` command. A filter option
begins with the literal `--filter`, followed by the category (e.g. `genre` or `artist`), then finally the text to
filter on, for instance `Rock` or `Santana` or `2012`. The text must be quoted if it contains whitespace.
If more that one filter is specified, they are treated as a logical AND, i.e. all the listed filters must apply to
a given song for it to be downloaded in that run.
Filter values are fuzzy. They are case insensitive, and use the `in` construct. So, for example, the filter string
`--filter song "edmund fitzgerald"` would match the song title "The Wreck of the Edmund Fitzgerald".
Filters allow very specific download selections to be run. For example, let's look for all songs by Rush
from the album Vapor Trails (the remixed version) authored by ejthedj:
@ -164,7 +174,7 @@ directory.
`c3dbdl` provides complete flexibility in the output file format. When downloading, use the `--file-structure`
option to set the file structure. This value is an interpolated string containing one or more field variables,
which are mapped at download file. The available fields are:
which are mapped at download time. The available fields are:
* `genre`: The genre of the song.
* `artist`: The artist of the song.

View File

@ -533,7 +533,11 @@ def download(_filters, _id, _desc, _limit, _file_structure):
if len(_filters) < 1:
add_to_pending = True
else:
add_to_pending = all(song[_filter[0]].lower() == _filter[1].lower() for _filter in _filters)
try:
add_to_pending = all(_filter[1].lower() in song[_filter[0]].lower() for _filter in _filters)
except KeyError:
click.echo(f"Invalid filter field {_filter[0]}")
exit(1)
if add_to_pending:
pending_songs.append(song)
@ -547,6 +551,61 @@ def download(_filters, _id, _desc, _limit, _file_structure):
downloadSong(config["download_directory"], _file_structure, song, _id, _desc)
@click.command(name="search", short_help="Search for songs from local C3DB.")
@click.option(
"-f",
"--filter",
"_filters",
envvar="C3DBDL_DL_FILTERS",
default=[],
multiple=True,
nargs=2,
help="Add a filter option.",
)
def search(_filters):
"""
Search for song(s) from the C3DB local database.
Filters allow granular selection of the song(s) to download. Multiple filters can be
specified, and a song is selected only if ALL filters match (logical AND). Each filter
is in the form "--filter [database_key] [value]".
For a full list of and explanation for filters, see the "download" command help
(command "c3dbdl download --help").
\b
The following environment variables can be used for scripting purposes:
* C3DBDL_DL_FILTERS: equivalent to "--filter"; limited to one instance
"""
with open(config["database_filename"], "r") as fh:
all_songs = json.load(fh)
click.echo(
f"Found {len(all_songs)} songs from JSON database file '{config['database_filename']}'"
)
pending_songs = list()
for song in all_songs:
if len(_filters) < 1:
add_to_pending = True
else:
try:
add_to_pending = all(_filter[1].lower() in song[_filter[0]].lower() for _filter in _filters)
except KeyError:
click.echo(f"Invalid filter field {_filter[0]}")
exit(1)
if add_to_pending:
pending_songs.append(song)
click.echo(f"Found {len(pending_songs)} matchin song files:")
for entry in pending_songs:
click.echo(
f"""> "{entry['artist']} - {entry['title']}" by {entry['author']}..."""
)
@click.group(context_settings=CONTEXT_SETTINGS)
@click.option(
"-u",
@ -619,6 +678,7 @@ database.add_command(edit_database)
cli.add_command(database)
cli.add_command(download)
cli.add_command(search)
def main():