-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdb.py
156 lines (131 loc) · 5.98 KB
/
db.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import os
import sqlite3
import datetime
import utils
last_location_time_key = "last_location_time"
CIPHER_KEY = "buJ&zb2u"
class BuffData:
def __init__(self):
buff_folder = os.path.join(os.environ['HOME'], '.hmsoft')
if not os.path.isdir(buff_folder):
os.makedirs(buff_folder)
db_filename = os.path.join(buff_folder, 'picture-data.db')
self._connection = sqlite3.connect(db_filename, timeout=30.0)
self._cursor = self._connection.cursor()
self._connection.execute(
"CREATE TABLE IF NOT EXISTS uploaded (file_name TEXT, photo_id TEXT UNIQUE, md5sum TEXT UNIQUE, "
"upload_date TEXT )")
self._connection.execute(
"CREATE TABLE IF NOT EXISTS location (timestamp INTEGER PRIMARY KEY, latitude REAL, longitude REAL, "
"altitude REAL, address TEXT )")
self._connection.execute("CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT)")
self.CIPHER_KEY = utils.get_cipher_key(CIPHER_KEY)
def set_setting(self, key, value):
with self._connection:
if value is None:
self._connection.execute("DELETE FROM settings WHERE key = ?", (key, ))
else:
self._connection.execute("INSERT OR REPLACE INTO settings (key, value) VALUES(?, ?)",
(key, value))
def save_secure_data(self, key, data):
value = None
if data is not None:
if isinstance(data, dict):
value = utils.vigenere_encode(self.CIPHER_KEY, utils.dict2csl(data))
self.set_setting(key, value)
def get_secure_data(self, key):
value = self.get_setting(key)
if value is not None:
data = utils.csl2dict(utils.vigenere_decode(self.CIPHER_KEY, str(value)))
return data
return None
def get_setting(self, key):
self._cursor.execute("SELECT value FROM settings WHERE key = ?", (key,))
result = self._cursor.fetchall()
if len(result) == 1:
return result[0][0]
return None
def add_locations(self, locations):
c = 0
last_time = 0
with self._connection:
for location in locations:
if location is None:
continue
self._connection.execute(
"INSERT OR IGNORE INTO location (timestamp, latitude, longitude, altitude) VALUES(?, ?, ?, ?) ",
location)
c += 1
if location[0] > last_time:
last_time = location[0]
if c > 0:
self._connection.execute("INSERT OR REPLACE INTO settings (key, value) VALUES(?, ?)",
(last_location_time_key, last_time))
return c
def get_location_from_timestamp(self, timestamp, offset=None):
if offset is None:
offset = 15
offset *= 1000 * 60
self._cursor.execute("SELECT latitude, longitude, address, timestamp FROM location WHERE timestamp <= ? AND "
"timestamp >= ? ORDER BY ABS(? - timestamp) LIMIT 1",
(timestamp + offset, timestamp - offset, timestamp,))
result = self._cursor.fetchall()
if len(result) == 1:
location = result[0]
lat, lon, add, time = location
if not add:
try:
from geopy.geocoders import Nominatim
geolocator = Nominatim()
address = geolocator.reverse(str(lat) + ", " + str(lon), exactly_one=True).address
if address:
location = lat, lon, address, time
with self._connection:
self._connection.execute("UPDATE location SET address=? WHERE timestamp = ?",
(address, time))
except Exception as e:
print e
pass
return location
return None
def add_location(self, location):
with self._connection:
self._connection.execute(
"INSERT OR IGNORE INTO location (timestamp, latitude, longitude, altitude)VALUES(?, ?, ?, ?) ",
location)
def _get_file_already_uploaded_dict(self, md5sum):
self._cursor.execute("SELECT photo_id, upload_date FROM uploaded WHERE md5sum = ? AND photo_id IS NOT NULL", (md5sum, ))
result = self._cursor.fetchall()
if len(result) == 1:
pid, udate = result[0]
return utils.csl2dict(pid), utils.csl2dict(udate)
return None, None
def file_already_uploaded(self, service_name, md5sum):
if service_name is None:
raise ValueError("service_name is not set")
d, u = self._get_file_already_uploaded_dict(md5sum)
if d is not None:
try:
return d[service_name] is not None
except KeyError:
return False
return False
def set_file_uploaded(self, file_name, service_name, photo_id, md5sum):
if service_name is None:
raise ValueError("service_name is not set")
d, u = self._get_file_already_uploaded_dict(md5sum)
date = datetime.datetime.now().isoformat()
if d is not None:
d[service_name] = photo_id
u[service_name] = date
ids = utils.dict2csl(d)
dates = utils.dict2csl(u)
with self._connection:
self._connection.execute(
"UPDATE uploaded SET photo_id = ?, upload_date = ? WHERE md5sum = ?",
(ids, dates, md5sum))
else:
with self._connection:
self._connection.execute(
"INSERT OR IGNORE INTO uploaded (file_name, photo_id, md5sum, upload_date)VALUES(?, ?, ?, ?) ",
(file_name, service_name + "=" + photo_id, md5sum, service_name + "=" + date,))