SongFilter: add special keyword "base"
Restores the features from the previous draft commands "findin" / "searchin".
This commit is contained in:
parent
b5fc21b9f4
commit
2aee1b86f3
1
NEWS
1
NEWS
|
@ -6,6 +6,7 @@ ver 0.18 (2012/??/??)
|
||||||
- new command "readcomments" lists arbitrary file tags
|
- new command "readcomments" lists arbitrary file tags
|
||||||
- new command "toggleoutput"
|
- new command "toggleoutput"
|
||||||
- "find"/"search" with "any" does not match file name
|
- "find"/"search" with "any" does not match file name
|
||||||
|
- "search" and "find" with base URI (keyword "base")
|
||||||
- search for album artist falls back to the artist tag
|
- search for album artist falls back to the artist tag
|
||||||
- re-add the "volume" command
|
- re-add the "volume" command
|
||||||
* input:
|
* input:
|
||||||
|
|
|
@ -1483,9 +1483,13 @@ OK
|
||||||
<para>
|
<para>
|
||||||
Finds songs in the db that are exactly
|
Finds songs in the db that are exactly
|
||||||
<varname>WHAT</varname>. <varname>TYPE</varname> can
|
<varname>WHAT</varname>. <varname>TYPE</varname> can
|
||||||
be any tag supported by MPD, or one of the two special
|
be any tag supported by MPD, or one of the three special
|
||||||
parameters — <parameter>file</parameter> to search by
|
parameters — <parameter>file</parameter> to search by
|
||||||
full path (relative to database root), and
|
|
||||||
|
full path (relative to the music directory),
|
||||||
|
<parameter>in</parameter> to restrict the search to
|
||||||
|
songs in the given directory (also relative to the music
|
||||||
|
directory) and
|
||||||
<parameter>any</parameter> to match against all
|
<parameter>any</parameter> to match against all
|
||||||
available tags. <varname>WHAT</varname> is what to find.
|
available tags. <varname>WHAT</varname> is what to find.
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -20,6 +20,16 @@
|
||||||
#include "DatabaseSelection.hxx"
|
#include "DatabaseSelection.hxx"
|
||||||
#include "SongFilter.hxx"
|
#include "SongFilter.hxx"
|
||||||
|
|
||||||
|
DatabaseSelection::DatabaseSelection(const char *_uri, bool _recursive,
|
||||||
|
const SongFilter *_filter)
|
||||||
|
:uri(_uri), recursive(_recursive), filter(_filter)
|
||||||
|
{
|
||||||
|
/* optimization: if the caller didn't specify a base URI, pick
|
||||||
|
the one from SongFilter */
|
||||||
|
if (uri.empty() && filter != nullptr)
|
||||||
|
uri = filter->GetBase();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DatabaseSelection::Match(const Song &song) const
|
DatabaseSelection::Match(const Song &song) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,9 +42,7 @@ struct DatabaseSelection {
|
||||||
const SongFilter *filter;
|
const SongFilter *filter;
|
||||||
|
|
||||||
DatabaseSelection(const char *_uri, bool _recursive,
|
DatabaseSelection(const char *_uri, bool _recursive,
|
||||||
const SongFilter *_filter=nullptr)
|
const SongFilter *_filter=nullptr);
|
||||||
:uri(_uri), recursive(_recursive), filter(_filter) {
|
|
||||||
}
|
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
bool Match(const Song &song) const;
|
bool Match(const Song &song) const;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Song.hxx"
|
#include "Song.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
|
#include "util/UriUtil.hxx"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
@ -43,6 +44,9 @@ locate_parse_type(const char *str)
|
||||||
if (StringEqualsCaseASCII(str, LOCATE_TAG_ANY_KEY))
|
if (StringEqualsCaseASCII(str, LOCATE_TAG_ANY_KEY))
|
||||||
return LOCATE_TAG_ANY_TYPE;
|
return LOCATE_TAG_ANY_TYPE;
|
||||||
|
|
||||||
|
if (strcmp(str, "base") == 0)
|
||||||
|
return LOCATE_TAG_BASE_TYPE;
|
||||||
|
|
||||||
return tag_name_parse_i(str);
|
return tag_name_parse_i(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +138,11 @@ SongFilter::Item::Match(const Tag &_tag) const
|
||||||
bool
|
bool
|
||||||
SongFilter::Item::Match(const Song &song) const
|
SongFilter::Item::Match(const Song &song) const
|
||||||
{
|
{
|
||||||
|
if (tag == LOCATE_TAG_BASE_TYPE) {
|
||||||
|
const auto uri = song.GetURI();
|
||||||
|
return uri_is_child_or_same(value.c_str(), uri.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (tag == LOCATE_TAG_FILE_TYPE) {
|
if (tag == LOCATE_TAG_FILE_TYPE) {
|
||||||
const auto uri = song.GetURI();
|
const auto uri = song.GetURI();
|
||||||
return StringMatch(uri.c_str());
|
return StringMatch(uri.c_str());
|
||||||
|
@ -159,6 +168,14 @@ SongFilter::Parse(const char *tag_string, const char *value, bool fold_case)
|
||||||
if (tag == TAG_NUM_OF_ITEM_TYPES)
|
if (tag == TAG_NUM_OF_ITEM_TYPES)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (tag == LOCATE_TAG_BASE_TYPE) {
|
||||||
|
if (!uri_safe_local(value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* case folding doesn't work with "base" */
|
||||||
|
fold_case = false;
|
||||||
|
}
|
||||||
|
|
||||||
items.push_back(Item(tag, value, fold_case));
|
items.push_back(Item(tag, value, fold_case));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -185,3 +202,13 @@ SongFilter::Match(const Song &song) const
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SongFilter::GetBase() const
|
||||||
|
{
|
||||||
|
for (const auto &i : items)
|
||||||
|
if (i.GetTag() == LOCATE_TAG_BASE_TYPE)
|
||||||
|
return i.GetValue();
|
||||||
|
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit the search to files within the given directory.
|
||||||
|
*/
|
||||||
|
#define LOCATE_TAG_BASE_TYPE (TAG_NUM_OF_ITEM_TYPES + 1)
|
||||||
|
|
||||||
#define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10
|
#define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10
|
||||||
#define LOCATE_TAG_ANY_TYPE TAG_NUM_OF_ITEM_TYPES+20
|
#define LOCATE_TAG_ANY_TYPE TAG_NUM_OF_ITEM_TYPES+20
|
||||||
|
|
||||||
|
@ -99,6 +104,13 @@ public:
|
||||||
const std::list<Item> &GetItems() const {
|
const std::list<Item> &GetItems() const {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the "base" specification (if there is one) or an
|
||||||
|
* empty string.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
std::string GetBase() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue