]> git.phdru.name Git - m_librarian.git/commitdiff
Search authors by name/surname/misc name
authorOleg Broytman <phd@phdru.name>
Sun, 27 Mar 2016 21:14:05 +0000 (00:14 +0300)
committerOleg Broytman <phd@phdru.name>
Sun, 27 Mar 2016 21:14:05 +0000 (00:14 +0300)
Add generic search (case sensitive and insensitive; exact search,
substring search and substring anchored to the start) and apply it to
authors.

m_librarian/search.py [new file with mode: 0644]
requirements.txt
scripts/ml-search.py [new file with mode: 0755]
setup.py

diff --git a/m_librarian/search.py b/m_librarian/search.py
new file mode 100644 (file)
index 0000000..10cfc28
--- /dev/null
@@ -0,0 +1,70 @@
+
+__all__ = [
+    'search_authors', 'search_books', 'search_extensions',
+    'search_genres', 'search_languages',
+]
+
+from sqlobject.sqlbuilder import AND, func
+from .db import Author, Book, Extension, Genre, Language
+
+
+def _search_exact(table, case_sensitive, values):
+    expressions = []
+    if case_sensitive:
+        for column, value in values.items():
+            expressions.append(getattr(table.q, column) == value)
+    else:
+        for column, value in values.items():
+            expressions.append(
+                func.lower(getattr(table.q, column)) == value.lower())
+    return AND(*expressions)
+
+
+def _search_start(table, case_sensitive, values):
+    expressions = []
+    if case_sensitive:
+        for column, value in values.items():
+            expressions.append(getattr(table.q, column).startswith(value))
+    else:
+        for column, value in values.items():
+            expressions.append(
+                func.lower(getattr(table.q, column)).startswith(value.lower()))
+    return AND(*expressions)
+
+
+def _search_substring(table, case_sensitive, values):
+    expressions = []
+    if case_sensitive:
+        for column, value in values.items():
+            expressions.append(getattr(table.q, column).contains(value))
+    else:
+        for column, value in values.items():
+            expressions.append(
+                func.lower(getattr(table.q, column)).contains(value.lower()))
+    return AND(*expressions)
+
+
+def _search(table, search_type, case_sensitive, values):
+    _search_f = globals()['_search_%s' % search_type]
+    conditions = _search_f(table, case_sensitive, values)
+    return table.select(conditions)
+
+
+def search_authors(search_type, case_sensitive, values):
+    return _search(Author, search_type, case_sensitive, values)
+
+
+def search_books(search_type, case_sensitive, values):
+    return _search(Book, search_type, case_sensitive, values)
+
+
+def search_extensions(search_type, case_sensitive, values):
+    return _search(Extension, search_type, case_sensitive, values)
+
+
+def search_genres(search_type, case_sensitive, values):
+    return _search(Genre, search_type, case_sensitive, values)
+
+
+def search_languages(search_type, case_sensitive, values):
+    return _search(Language, search_type, case_sensitive, values)
index 4147751c9e7caae912a152aa248c1fd2faebd78d..88acdf5347f53771842d05d6c964a1576e181044 100644 (file)
@@ -1 +1,2 @@
 SQLObject
+m_lib
diff --git a/scripts/ml-search.py b/scripts/ml-search.py
new file mode 100755 (executable)
index 0000000..403780a
--- /dev/null
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+# coding: utf-8
+
+import argparse
+from m_lib.defenc import default_encoding
+from m_librarian.search import search_authors, search_books, \
+    search_extensions, search_genres, search_languages
+
+
+def _search_authors(args):
+    values = {}
+    for column in 'surname', 'name', 'misc':
+        value = getattr(args, column)
+        if value:
+            values[column] = unicode(value, default_encoding)
+    for author in search_authors(args.search_type, args.case_sensitive,
+                                 values):
+        full_name = filter(None,
+                           (author.surname, author.name, author.misc_name))
+        full_name = u' '.join(full_name)
+        print full_name.encode(default_encoding), \
+            u"(книг: %d)".encode(default_encoding) % author.count
+
+
+if __name__ == '__main__':
+    main_parser = argparse.ArgumentParser(description='Search')
+    main_parser.add_argument('-I', '--case-sensitive',
+                             action='store_true',
+                             help='don\'t ignore case '
+                             '(default is case-insensitive search)')
+    main_parser.add_argument('-t', '--search-type',
+                             choices=['exact', 'start', 'substring'],
+                             help='search type: '
+                             'exact match, substring at the start '
+                             '(this is the default), substring anywhere')
+    subparsers = main_parser.add_subparsers(help='Commands')
+
+    parser = subparsers.add_parser('authors', help='Search authors')
+    parser.add_argument('-s', '--surname', help='search by surname')
+    parser.add_argument('-n', '--name', help='search by name')
+    parser.add_argument('-m', '--misc', help='search by misc. name')
+    parser.set_defaults(func=_search_authors)
+
+    args = main_parser.parse_args()
+    args.func(args)
index d61682026e881dee896806bd2b15e0575f9c47e3..f649f3e23910cb859cfcf76c67aeeb20b05c8225 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -44,5 +44,5 @@ setup(name='m_librarian',
       packages=['m_librarian'],
       package_data={'m_librarian': ['glst/*.txt', 'glst/genres_*.glst']},
       scripts=['scripts/ml-import.py', 'scripts/ml-initdb.py'],
-      requires=['SQLObject'],
+      requires=['SQLObject', 'm_lib'],
       )