· 8 years ago · Jul 21, 2018, 07:50 PM
1import datetime
2import os
3import sqlite3
4import sys
5
6import fsscan
7
8
9class EntriesDB:
10
11 def __init__(self, database):
12 self.database = database
13 self.connection = sqlite3.connect(database)
14
15 def __repr__(self):
16 return "<%s(%s)>" % (self.__class__.__name__, self.database)
17
18 def __del__(self):
19 self.close()
20
21 def close(self):
22 self.connection.close()
23
24 def table_already_exists(self):
25 query = """
26 SELECT name
27 FROM sqlite_master
28 WHERE type='table' AND name='entries';
29 """
30 with self.connection:
31 cursor = self.connection.execute(query)
32 result = cursor.fetchone()
33 return result and 'entries' in result
34
35 def create_new_table(self):
36 self.delete_table()
37 self.create_table()
38
39 def delete_table(self):
40 query = """DROP TABLE IF EXISTS entries;"""
41 self.execute(query)
42
43 def create_table(self):
44 query = """
45 CREATE TABLE entries (
46 disk TEXT,
47 partition TEXT,
48 path TEXT,
49 name TEXT,
50 size NUMERIC,
51 created TEXT,
52 accessed TEXT,
53 modified TEXT
54 );
55 """
56 self.execute(query)
57
58 def insert_rows(self, rows):
59 query = """INSERT INTO entries VALUES (?, ?, ?, ?, ?, ?, ?, ?);"""
60 self.execute_many(query, rows)
61
62 def execute(self, query):
63 with self.connection:
64 self.connection.execute(query)
65
66 def execute_many(self, query, params):
67 with self.connection:
68 self.connection.executemany(query, params)
69
70
71def get_path_stats(entries, disk, partition):
72 fse = sys.getfilesystemencoding()
73 for entry in entries:
74
75 try:
76 # Some entries are no decodable
77 entry = str(entry).encode(fse, errors="strict").decode(fse)
78 except UnicodeEncodeError:
79 # Replace non decodable characters with '?'
80 entry = str(entry).encode(fse, errors="replace").decode(fse)
81 print("Encoding error with %s" % entry, file=sys.stderr)
82 continue
83
84 entry_name = os.path.basename(entry)
85 stats = os.stat(entry, follow_symlinks=False)
86 ctime = datetime.datetime.fromtimestamp(stats.st_ctime)
87 atime = datetime.datetime.fromtimestamp(stats.st_atime)
88 mtime = datetime.datetime.fromtimestamp(stats.st_mtime)
89 yield (
90 disk, partition, entry, entry_name,
91 stats.st_size, ctime, atime, mtime
92 )
93
94
95def main():
96 database = "fsscan_entries.db"
97 db = EntriesDB(database)
98
99 if not db.table_already_exists():
100 db.create_table()
101
102 config = {
103 "current_working_dir": os.getcwd(),
104 # "disk1": "path_to_directory_1",
105 # "disk2": "path_to_directory_2",
106 }
107
108 for disk, directory in config.items():
109
110 partition = os.path.basename(directory)
111
112 time0 = datetime.datetime.utcnow()
113
114 entries = fsscan.run(directory, recursive=True)
115 entries = get_path_stats(entries, disk, partition)
116
117 db.insert_rows(entries)
118
119 time1 = datetime.datetime.utcnow()
120 print("Done ! (%s - %s)" % ((time1 - time0), directory))
121
122
123if __name__ == '__main__':
124 main()