X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;f=tags.py;h=3fe860bdfab7fcfaa196726a11fc9bcae95ca7b0;hb=HEAD;hp=7ff886d544ec0a70bc9f8eb6926633671ab872f4;hpb=ed552696f81f160ff233a268cbc9b506e76edce9;p=phdru.name%2Fcgi-bin%2Fblog-ru%2Fsearch-tags.git diff --git a/tags.py b/tags.py index 7ff886d..92a3706 100644 --- a/tags.py +++ b/tags.py @@ -1,25 +1,84 @@ blog_filename = "blog_dict.pickle" try: - import cPickle as pickle + import cPickle as pickle except ImportError: - import pickle + import pickle try: - blog_file = open(blog_filename, "rb") + blog_file = open('../../../../phdru.name/ru/' + blog_filename, "rb") except IOError: - blog_dict = {} + blog_dict = {} else: - blog_dict = pickle.load(blog_file) - blog_file.close() + blog_dict = pickle.load(blog_file) + blog_file.close() # blog_dict is a mapping # (year, month, day) => [list of (file, title, lead, tags)] -def tag_exists(tag): - for posts in blog_dict.itervalues(): - for _file, _title, _lead, tags in posts: - if tag in tags: - return True - return False +# Add lower-case tags +_new_dict = {} +for (year, month, day), posts in blog_dict.items(): + _new_dict[year, month, day] = _posts = [] + for _file, _title, _lead, _tags in posts: + tags_lower = [tag.lower().replace(' ', '_') for tag in _tags] + _posts.append((_file, _title, _lead, _tags, tags_lower)) +blog_dict = _new_dict + + +def real_tag(tag): + ltag = tag.lower().replace(' ', '_') + for posts in blog_dict.values(): + for _file, _title, _lead, _tags, _tags_lower in posts: + try: + ix = _tags_lower.index(ltag) + except ValueError: + continue + else: + return _tags[ix].replace(' ', '_') + + +def _test_post(post, tree): + """Test if the list of tags in the post satisfies condition + + Recursively evaluate the tree against the list of tags in the post. + + """ + op = tree[0] + if op == 'NAME': + tag = tree[1] + assert isinstance(tag, str) + return tag.lower().replace(' ', '_') in post[4] + elif op in ('AND', 'OR'): + value1 = _test_post(post, tree[1]) + value2 = _test_post(post, tree[2]) + if op == 'AND': + return value1 and value2 + if op == 'OR': + return value1 or value2 + elif op == 'NOT': + return not _test_post(post, tree[1]) + elif op == 'PARENS': + return _test_post(post, tree[1]) + else: + raise ValueError("Cannot get there") + + +def find_tags(tree): + """Test every blog post against parsed expression + + Return all posts that passed the test. + + """ + _posts = [] + for (year, month, day), posts in blog_dict.items(): + for post in posts: + if _test_post(post, tree): + _posts.append(( + year, month, day, + '/'.join( + (year, month, day, post[0][:-len("tmpl")] + "html")), + post[1])) + _posts.sort(reverse=True) + return _posts