Edouard@2339: #!/usr/bin/env python Edouard@2339: # -*- coding: utf-8 -*- Edouard@2339: Edouard@2339: # See COPYING file for copyrights details. Edouard@2339: Edouard@2339: from __future__ import absolute_import Edouard@2339: import os Edouard@2339: import time Edouard@2339: import json Edouard@2339: Edouard@2339: COL_ID,COL_URI,COL_DESC,COL_LAST = range(4) Edouard@2339: Edouard@2339: def _pskpath(project_path): Edouard@2339: return os.path.join(project_path, 'psk') Edouard@2339: Edouard@2339: def _mgtpath(project_path): Edouard@2339: return os.path.join(_pskpath(project_path), 'management.json') Edouard@2339: Edouard@2339: def _default(): Edouard@2339: return ['', # default description Edouard@2339: None, # last known URI Edouard@2339: None] # last connection date Edouard@2339: Edouard@2339: def _LoadData(project_path): Edouard@2339: if os.path.isdir(_pskpath(project_path)): Edouard@2339: _path = _mgtpath(project_path) Edouard@2339: # load known keys metadata Edouard@2339: # {ID:(Desc, LastKnownURI, LastConnect)} Edouard@2339: return json.loads(open(_path).read()) \ Edouard@2339: if os.path.exists(_path) else {} Edouard@2339: return {} Edouard@2339: Edouard@2339: def GetData(project_path): Edouard@2339: # [(ID, Desc, LastKnownURI, LastConnect) Edouard@2339: data = [] Edouard@2339: loaded_data = _LoadData(project_path) Edouard@2339: # go through all secret files available an build data Edouard@2339: # out of data recoverd from json and list of secret. Edouard@2339: # this implicitly filters IDs out of metadata who's Edouard@2339: # secret is missing Edouard@2339: psk_files = os.listdir(_pskpath(project_path)) Edouard@2339: for filename in psk_files: Edouard@2339: if filename.endswith('.secret'): Edouard@2339: ID = filename[:-7] # strip filename extension Edouard@2339: meta = loaded_data.get(ID,_default()) Edouard@2339: data.append([ID]+meta) Edouard@2339: return data Edouard@2339: Edouard@2339: Edouard@2339: def DeleteID(project_path, ID): Edouard@2339: secret_path = os.path.join(_pskpath(project_path), ID+'.secret') Edouard@2339: os.remove(secret_path) Edouard@2339: Edouard@2339: def _StoreData(project_path, data): Edouard@2339: pskpath = _pskpath(project_path) Edouard@2339: if not os.path.isdir(pskpath): Edouard@2339: os.mkdir(pskpath) Edouard@2339: with open(_mgtpath(project_path), 'w') as f: Edouard@2339: f.write(json.dumps(data)) Edouard@2339: Edouard@2339: def SaveData(project_path, data): Edouard@2339: to_store = {row[0]:row[1:] for row in data} Edouard@2339: _StoreData(project_path, to_store) Edouard@2339: Edouard@2339: def UpdateID(project_path, ID, secret, URI): Edouard@2339: pskpath = _pskpath(project_path) Edouard@2339: if not os.path.exists(pskpath): Edouard@2339: os.mkdir(pskpath) Edouard@2339: Edouard@2339: secpath = os.path.join(pskpath, ID+'.secret') Edouard@2339: with open(secpath, 'w') as f: Edouard@2339: f.write(ID+":"+secret) Edouard@2339: Edouard@2339: data = _LoadData(project_path) Edouard@2339: dataForID = [ID] + (data.get(ID, _default()) if data else _default()) Edouard@2339: dataForID[COL_URI] = URI Edouard@2339: # FIXME : could store time instead os a string and use DVC model's cmp Edouard@2339: # then date display could be smarter, etc - sortable sting hack for now Edouard@2339: dataForID[COL_LAST] = time.strftime('%y/%M/%d-%H:%M:%S') Edouard@2339: data[ID] = dataForID[1:] Edouard@2339: _StoreData(project_path, data)