17
17
18
18
"""Functions that manage a platform database"""
19
19
20
+ import datetime
20
21
import json
21
22
import re
22
23
from collections import OrderedDict
23
24
from copy import copy
24
25
from io import open
25
26
from os import makedirs
26
- from os .path import join , dirname
27
+ from os .path import join , dirname , getmtime
27
28
from appdirs import user_data_dir
28
29
from fasteners import InterProcessLock
29
30
32
33
except NameError :
33
34
unicode = str
34
35
36
+
35
37
import logging
36
38
logger = logging .getLogger ("mbedls.platform_database" )
37
39
del logging
251
253
u'RIOT' : u'RIOT' ,
252
254
}
253
255
256
+
257
+ def _get_modified_time (path ):
258
+ try :
259
+ mtime = getmtime (path )
260
+ except OSError :
261
+ mtime = 0
262
+ return datetime .date .fromtimestamp (mtime )
263
+
264
+
265
+ def _older_than_me (path ):
266
+ return _get_modified_time (path ) < _get_modified_time (__file__ )
267
+
268
+
269
+ def _overwrite_or_open (db ):
270
+ try :
271
+ if db is LOCAL_PLATFORM_DATABASE and _older_than_me (db ):
272
+ raise ValueError ("Platform Database is out of date" )
273
+ with open (db , encoding = "utf-8" ) as db_in :
274
+ return json .load (db_in )
275
+ except (IOError , ValueError ) as exc :
276
+ if db is LOCAL_PLATFORM_DATABASE :
277
+ logger .warning (
278
+ "Error loading database %s: %s; Recreating" , db , str (exc ))
279
+ try :
280
+ makedirs (dirname (db ))
281
+ except OSError :
282
+ pass
283
+ with open (db , "w" , encoding = "utf-8" ) as out :
284
+ out .write (unicode (json .dumps (DEFAULT_PLATFORM_DB )))
285
+ return copy (DEFAULT_PLATFORM_DB )
286
+ else :
287
+ return {}
288
+
289
+
254
290
class PlatformDatabase (object ):
255
291
"""Represents a union of multiple platform database files.
256
292
Handles inter-process synchronization of database files.
@@ -266,42 +302,15 @@ def __init__(self, database_files, primary_database=None):
266
302
self ._dbs = OrderedDict ()
267
303
self ._keys = set ()
268
304
for db in database_files :
269
- try :
270
- with open (db , encoding = "utf-8" ) as db_json_file :
271
- new_db = json .load (db_json_file )
272
- duplicates = set (self ._keys ).intersection (set (new_db .keys ()))
273
- if duplicates :
274
- logger .warning (
275
- "Duplicate platform ids found: %s,"
276
- " ignoring the definitions from %s" ,
277
- " " .join (duplicates ), db )
278
- self ._dbs [db ] = new_db
279
- self ._keys = self ._keys .union (new_db .keys ())
280
- except IOError as exc :
281
- if db is LOCAL_PLATFORM_DATABASE :
282
- logger .warning (
283
- "Could not open local platform database at %s; "
284
- "Recereating" , db )
285
- try :
286
- makedirs (dirname (db ))
287
- except OSError :
288
- pass
289
- with open (db , "w" , encoding = "utf-8" ) as out :
290
- out .write (unicode (json .dumps (DEFAULT_PLATFORM_DB )))
291
- new_db = copy (DEFAULT_PLATFORM_DB )
292
- self ._dbs [db ] = new_db
293
- self ._keys = self ._keys .union (new_db .keys ())
294
- else :
295
- if db is not self ._prim_db :
296
- logger .error (
297
- "Could not open platform database %s: %s; skipping" ,
298
- db , str (exc ))
299
- self ._dbs [db ] = {}
300
- except ValueError as exc :
301
- logger .error (
302
- "Could not parse platform database %s because %s; "
303
- "skipping" , db , str (exc ))
304
- self ._dbs [db ] = {}
305
+ new_db = _overwrite_or_open (db )
306
+ duplicates = set (self ._keys ).intersection (set (new_db .keys ()))
307
+ if duplicates :
308
+ logger .warning (
309
+ "Duplicate platform ids found: %s,"
310
+ " ignoring the definitions from %s" ,
311
+ " " .join (duplicates ), db )
312
+ self ._dbs [db ] = new_db
313
+ self ._keys = self ._keys .union (new_db .keys ())
305
314
306
315
def items (self ):
307
316
for db in self ._dbs .values ():
0 commit comments