]> git.phdru.name Git - phdru.name/cgi-bin/blog-ru/search-tags.git/blobdiff - tags.py
Version 0.8: Python 3
[phdru.name/cgi-bin/blog-ru/search-tags.git] / tags.py
diff --git a/tags.py b/tags.py
index 7ff886d544ec0a70bc9f8eb6926633671ab872f4..92a37060cc32c81f3bddb7838795cc683e8548e4 100644 (file)
--- 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