]> git.phdru.name Git - m_librarian.git/blob - m_librarian/inp.py
Cleanup: Fix flake8 E741 ambiguous variable name 'l'
[m_librarian.git] / m_librarian / inp.py
1
2 import os
3 from zipfile import ZipFile
4 from sqlobject import sqlhub
5 from sqlobject.sqlbuilder import Select
6 from .db import Author, Book, Extension, Genre, Language, \
7     insert_name, insert_author
8
9 __all__ = ['import_inpx']
10
11
12 EOT = chr(4)  # INP field separator
13
14
15 def split_line(line):
16     parts = line.strip().split(EOT)
17     _l = len(parts)
18     if _l < 11:
19         raise ValueError('Unknown INP structure: "%s"' % line)
20     if _l == 11:  # Standard structure
21         parts.append(None)  # Emulate lang
22     else:  # New structure
23         parts = parts[:12]
24     return parts
25
26
27 def import_inp_line(archive, parts):
28     authors, genres, title, series, ser_no, file, size, lib_id, deleted, \
29         extension, date, language = parts
30     try:
31         ser_no = int(ser_no)
32     except ValueError:
33         ser_no = None
34     size = int(size)
35     deleted = deleted == '1'
36     extension_row = insert_name(Extension, extension)
37     language_row = insert_name(Language, language)
38     book = Book(title=title, series=series, ser_no=ser_no,
39                 archive=archive, file=file, size=size,
40                 lib_id=lib_id, deleted=deleted,
41                 extension=extension_row, date=date,
42                 language=language_row)
43     authors = authors.split(':')
44     seen_authors = set()
45     for author in authors:
46         if author:
47             if author in seen_authors:
48                 continue
49             seen_authors.add(author)
50             alist = author.split(',', 2)
51             surname = alist[0]
52             if len(alist) > 1:
53                 name = alist[1]
54                 if len(alist) == 3:
55                     misc_name = alist[2]
56                 else:
57                     misc_name = ''
58             else:
59                 name = misc_name = ''
60             author_row = insert_author(surname, name, misc_name)
61             book.addAuthor(author_row)
62     for genre in genres.split(':'):
63         if genre:
64             genre_row = insert_name(Genre, genre, title=genre)
65             book.addGenre(genre_row)
66
67
68 def import_inp(archive, inp):
69     files = set()
70     connection = sqlhub.processConnection
71     for file, in connection.queryAll(connection.sqlrepr(
72             Select(Book.q.file, Book.q.archive == archive))):
73         files.add(file)
74     for line in inp:
75         line = line.decode('utf-8')
76         parts = split_line(line)
77         file = parts[5]
78         if file not in files:
79             files.add(file)
80             import_inp_line(archive, parts)
81
82
83 def import_inpx(path):
84     inpx = ZipFile(path)
85     for name in inpx.namelist():
86         archive, ext = os.path.splitext(name)
87         if ext != '.inp':
88             continue
89         inp = inpx.open(name)
90         sqlhub.doInTransaction(import_inp, archive + '.zip', inp)
91         inp.close()
92     connection = sqlhub.processConnection
93     if connection.dbName == 'postgres':
94         for table in Author, Book, Extension, Genre, Language:
95             connection.query("VACUUM %s" % table.sqlmeta.table)
96     elif connection.dbName == 'sqlite':
97         connection.query("VACUUM")