]> git.phdru.name Git - xsetbg.git/blob - rescan_fs.py
Fix(DB): Fix column encoding
[xsetbg.git] / rescan_fs.py
1 #! /usr/bin/env python3
2 """Rescan filesystem and update database
3
4 Rescan images directories; remove unknown images from DB; add new images.
5
6 This file is a part of XSetBg.
7
8 """
9
10 import os
11 import subprocess
12
13 from sqlobject import SQLObjectNotFound
14 from sqlobject.sqlbuilder import Insert, Update, Delete
15 from m_lib.defenc import default_encoding
16
17 from xsetbg_conf import xsetbg_dir, xsetbg_conf
18 from xsetbg_db import recreate_db, SQLiteMassInsert
19
20 if xsetbg_conf.has_option("images", "directory") or \
21         xsetbg_conf.has_option("images", "directory0") or \
22         xsetbg_conf.has_option("images", "directory1"):
23     image_dirs = []
24     if xsetbg_conf.has_option("images", "directory"):
25         image_dirs.append(xsetbg_conf.get("images", "directory"))
26     if xsetbg_conf.has_option("images", "directory0"):
27         image_dirs.append(xsetbg_conf.get("images", "directory0"))
28     if xsetbg_conf.has_option("images", "directory1"):
29         image_dirs.append(xsetbg_conf.get("images", "directory1"))
30     i = 2
31     while True:
32         option = "directory%d" % i
33         if xsetbg_conf.has_option("images", option):
34             image_dirs.append(xsetbg_conf.get("images", option))
35             i += 1
36         else:
37             break
38 else:
39     image_dirs = ["images"]
40
41 image_dirs = [
42     os.path.join(xsetbg_dir, os.path.expandvars(os.path.expanduser(dirname)))
43     for dirname in image_dirs
44 ]
45
46 fs_encoding = xsetbg_conf.get("images", "fs_encoding")
47 xsetbg_db = recreate_db()
48 count_new = count_old = count_del = 0
49
50 NULL = open(os.devnull, 'w')
51
52
53 def is_image(full_path):
54     # Run `identify` from ImageMagic; convert retcode to bool
55     return not subprocess.call(['identify', full_path.encode(fs_encoding)],
56                                stdout=NULL, stderr=subprocess.STDOUT)
57
58
59 with SQLiteMassInsert() as txn:
60     for image_dir in image_dirs:
61         # List images in all subdirectories
62         for dirpath, dirs, files in os.walk(image_dir):
63             for file in files:
64                 if default_encoding != fs_encoding:
65                     file = file.encode().decode(fs_encoding)
66                 full_name = os.path.join(dirpath, file)
67                 try:
68                     row = xsetbg_db.byFull_name(full_name)
69                 except SQLObjectNotFound:
70                     values = {'full_name': full_name,
71                               'is_image': is_image(full_name),
72                               'flag': True,
73                               }
74                     query = txn.sqlrepr(Insert(xsetbg_db.sqlmeta.table,
75                                                values=values))
76                     txn.query(query)
77                     count_new += 1
78                 else:
79                     if row.is_image is None:
80                         row.is_image = is_image(full_name)
81                     row.flag = True
82                     count_old += 1
83     count_del = xsetbg_db.select('flag IS NULL').count()
84     query = txn.sqlrepr(Delete(xsetbg_db.sqlmeta.table, 'flag IS NULL'))
85     txn.query(query)
86     query = txn.sqlrepr(Update(xsetbg_db.sqlmeta.table, {'flag': None}))
87     txn.query(query)
88
89 NULL.close()
90 print("New images:", count_new)
91 print("Existing images:", count_old)
92 print("Removed images:", count_del)