-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdb.py
217 lines (170 loc) · 5.71 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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import os
import json
import fire
from datetime import datetime
DB_FILE = 'db.json'
ENV_FILE = 'env.json'
DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
class Database(object):
"""Storage class to keep track of gist sync information.
This class is independent of the actual implementation
of the database, thus make it easier to change in the future.
"""
def __init__(self):
if not os.path.isfile(DB_FILE) or not os.path.isfile(ENV_FILE):
self.info = {"num_gists": 0}
self.env = {
"cold_start": True,
"sync_at": datetime.strftime(datetime(1990, 10, 22), DATE_FORMAT)}
self.sync_info("save")
self.sync_env("save")
return
# restore db and env from previous execution result
self.sync_info('load')
self.sync_env('load')
def is_empty(self):
"""Indicate whether there is any gist in database.
Returns
-------
bool
"""
return self.info.get('num_gists', 0) == 0
def is_cold_start(self):
"""Indicate whether it is needed to synchronize all gists.
Returns
-------
bool
"""
return self.env.get('cold_start', True)
def get_last_sync(self):
"""Return the UTC datetime indicating the last synchronization
Returns
-------
last_sync_date : datetime.datetime
"""
return datetime.strptime(self.env['sync_at'], DATE_FORMAT)
def toggle_cold_start(self):
"""Toggle value of cold_start"""
self.env['cold_start'] = not self.env.get('cold_start', True)
self.sync_env('save')
def get_hash_by_id(self, gist_id):
"""Get hash value of the gist using `gist_id` as key
Parameters
----------
gist_id : str
Unique gist identifier called `id` available in Github API
e.g. "MDQ6R2lzdGUzOTNkODgxMjIyODg1ZjU5ZWYwOWExNDExNzE1OWM4"
Returns
-------
hash : str
"" if no gist can be found in database by `gist_id`
"""
return self.info.get(gist_id, {}).get('hash', '')
def get_note_guid_by_id(self, gist_id):
"""Get guid of note related to the gist with `gist_id`
Parameters
----------
gist_id : str
Unique gist identifier called `id` available in Github API
e.g. "MDQ6R2lzdGUzOTNkODgxMjIyODg1ZjU5ZWYwOWExNDExNzE1OWM4"
Returns
-------
guid : str
"""
return self.info.get(gist_id, {}).get('note_guid', '')
def save_gist(self, gist, note_guid, hash):
"""Save information of a given gist into database.
Parameters
----------
gist : dict
A Gist acquired by Github GraphQL API with format like:
{
'id': 'gist_id',
'name': 'gist_name',
'description': 'description',
'pushedAt': '2018-01-15T00:48:23Z',
}
note_guid : str
hash : str
"""
gist['note_guid'] = note_guid
gist['hash'] = hash
self.info[gist['id']] = gist
self.info['num_gists'] = self.info.get('num_gists', 0) + 1
self.sync_info('save')
self.update_sync_time(gist['pushedAt'])
def update_gist(self, gist, note_guid, hash):
"""Update information of a given gist into database.
Parameters
----------
gist : dict
A Gist acquired by Github GraphQL API with format like:
{
'id': 'gist_id',
'name': 'gist_name',
'description': 'description',
'pushedAt': '2018-01-15T00:48:23Z'
}
note_guid : str
hash : str
"""
gist['note_guid'] = note_guid
gist['hash'] = hash
self.info[gist['id']] = gist
self.sync_info('save')
self.update_sync_time(gist['pushedAt'])
def update_sync_time(self, sync_date):
"""Update last synchronization time
Parameters
----------
sync_date : str
String indicating valid datetime like '2018-01-15T00:48:23Z',
which defined by global environment `DATE_FORMAT`.
"""
self.env['sync_at'] = sync_date
self.sync_env('save')
def sync_env(self, mode):
"""Synchronize runtime information between current Database obj and permanent storage
Parameters
----------
mode : str
Indicating to save or load environment. Valid values: ["save", "load"]
Returns
-------
bool
"""
if mode == 'save':
with open(ENV_FILE, 'w') as fp:
json.dump(self.env, fp, indent=2)
elif mode == 'load':
with open(ENV_FILE, "r") as fp:
env = json.load(fp)
self.env = env
return True
def sync_info(self, mode):
"""Synchronize gist info between current Database obj and permanent storage
Parameters
----------
mode : str
Indicating to save or load environment. Valid values: ["save", "load"]
Returns
-------
bool
"""
if mode == 'save':
with open(DB_FILE, 'w') as fp:
json.dump(self.info, fp, indent=2)
elif mode == 'load':
with open(DB_FILE, "r") as fp:
info = json.load(fp)
self.info = info
return True
def get_db():
"""Get a database instance for storing gist information
Returns
-------
db : Database instance
"""
return Database()
if __name__ == '__main__':
fire.Fire()