This experiment of bringing Photos and Albums closer to parity in
search is going well so far. I have found some situations where it
is nice to only get albums back from search results.
There was always some semblance that two blank lines has some kind of
meaning or structure that's different from single blank lines, but
in reality it was mostly arbitrary and I can't stand to look at it
any more.
At some point, I changed tag_export.flat_dict from using strings as
keys to using actual Tag objects as keys. The tag expression handler
never got updated, so frozen_children[tagname] raised KeyError as
it was looking for a string.
I considered using tag_expression_tree.map to convert all the tree
tokens into tag objects, but when we render the tree back into text
it will say "Tag:name" instead of just "name" throughout the whole
expression, and I don't want to deal with converting those back.
The problem was that during the expansion of A, B would get added to
the `total` set. And then because B was already in total, it would
bail early instead of expanding, but that meant it got left out of
the final query. But this only happened sometimes since random set
ordering would sometimes expand B before A and everything was ok.
I think the best solution is to do this first pass that eliminates
ancestors. Furthermore, I realized that the entirety of expand_nested
hinged on this flawed logic and was otherwise completely redundant
for a simple list comprehension.
Added a styleguide.md file to refer back to.
Since voussoirkit is a library it feels better to have it below
the rest of the library and above the local project imports.
I found that the strict heirarchy was not satisfying the situation
where one tag is the intersection of two others, but we can only
pick one as the parent
For example, does red_jacket belong under clothes.red_clothes or
clothes.jackets? A search for "red_clothes AND jackets" might
give us someone wearing red pants and a black jacket, so this
definitely needs to be a separate tag, but picking only one
parent for it is not sufficient. Now, a search for red_clothes
and a search for jackets will both find our red_jacket photo.
The change also applies to Albums because why not, and I'm sure
a similar case can be made.
Unfortunately this means tags no longer have one true qualname.
The concept of qualnames has not been completely phased out but
it's in progress.
This commit is very big because I was not sure for a long time
whether to go through with it, and so much stuff had to change
that I don't want to go back and figure out what could be grouped
together.
It was getting difficult to remember which of the normalizers
use None and which don't. So let's try to be a little more consistent
and just use empty sets, etc, so the caller can rely on receiving a
set instead of having to check for None.
Also renamed search parameter authors->author to be more in line
with the singular form of extension.
In order to achieve tag_musts, we break each of the musts down
into separate EXISTS queries for each of the matchable children.
Then we INTERSECT those, and finally do other filtering and
ordering as usual.
By default, photos with searchhidden do not appear in the search
results. This allows a small number of representative images from
a large album to appear in the results, while the rest can be
found on the album's page.
The same effect could be achieved with a tag and forbid search,
but tag searching has much higher cost and it would be more difficult
to implement as a default behavior without requiring lots of special
checks whenever listing tags etc.
fix bug in which renaming photo causes os.remove even when it's an in-place rename on case-insensitive systems; incorporate expressionmatch for filename search; minor comment cleanup
add photo and search css for narrow screens; incorporate new expressionmatch kit; entry_with_history cursor moves to end; albums indicate total filesize; etc