diff --git a/.init.sh.un~ b/.init.sh.un~ deleted file mode 100644 index 07c1ff0..0000000 Binary files a/.init.sh.un~ and /dev/null differ diff --git a/src/api/index.py b/src/api/index.py index 5999009..db1494e 100644 --- a/src/api/index.py +++ b/src/api/index.py @@ -25,7 +25,7 @@ import re import monitor import uuid -import Queue +from utils.register import Register from utils.transport import * from utils.agents import actor @@ -81,7 +81,28 @@ def home(): return render_template('dashboard.html',context=context,title=title,app_names=apps) @app.route('/register',methods=['POST']) -def register(): +def register() : + """ + This function registers a user and provides + """ + global p + body = request.get_json(silent=True) + uid = body['uid'] + default_plan = CONFIG['plan'] + if 'plan' not in body : + plan = CONFIG['plan'] + else: + plan = body['plan'] + handler = Register(write=class_write,read=class_read,store=p,default=default_plan,uid=uid) + r = handler.register(plan) + if not r : + info = handler.get_info() + return "" if info is None else json.dumps(info) + else: + print r + return json.dumps(r) + +def __register(): """ This function is intended to manage users i.e : register a user given an email Once the email is provided a key will be generated for the user @@ -92,13 +113,18 @@ def register(): global p body = request.get_json(silent=True) - - auid = str(uuid.uuid4()) - headers = {"uid":body['uid'],"pid":body['plan'],"auid":json.dumps([auid])} + # + # Before we start we must insure the user actually exists + # couchdb = factory.instance(type=class_read,args=p) r = couchdb.view('federation/uid_map',key=body['uid']) - q = couchdb.view('federation/uid_map',key=auid) - if not r and not q: + + if not r : + body['plan'] = CONFIG['plan'] + auid = str(uuid.uuid4()) + + headers = {"uid":body['uid'],"pid":body['plan'],"auid":json.dumps([auid])} + q = couchdb.view('federation/uid_map',key=auid) # The uid has not yet been assigned url="https://the-phi.com/store/init/monitor" @@ -108,12 +134,13 @@ def register(): # Now we should create a document with the generated key # @TODO: Have an endpoint map uid/key args = dict(p) - - args['dbname'] = body['plan'] + args['dbname'] = body['plan'] + #args['dbname'] = body['plan'] args['uid'] = auid couchdb = factory.instance(type=class_write,args=args) couchdb.write(label='emails',row=[auid,body['uid']]) + # couchdb.write(label='emails',row=[auid]) plan = {body['plan']:json.loads(r.text)} session['plan'] = [plan] couchdb.write(label='plan',row=plan) @@ -128,9 +155,16 @@ def register(): # args = dict(p) - args['uid'] = r #-- returned uid + couchdb = factory.instance(type=class_read,args=args) + args['uid'] = r #-- returned uid + plan = couchdb.view('plans/active',key=r) + args['dbname'] = plan['id'] + # + # get the new table i.e user's auid + args['uid'] = body['uid'] couchdb = factory.instance(type=class_read,args=args) document = couchdb.read() + print args,document r = list(set(document['emails']) - set(body['uid'])) r = [item for item in r if len(item) == 36] if len(r) > 0 : diff --git a/src/utils/register.py b/src/utils/register.py new file mode 100644 index 0000000..f1336d4 --- /dev/null +++ b/src/utils/register.py @@ -0,0 +1,113 @@ +""" + + This class handles user registration i.e : + - The first time a user logs in (default plan i.e free) + - change of plan + - cancel plan + + The class is +""" +from utils.transport import * +import uuid +import requests + +class Register : + def __init__(self,**args) : + """ + @param read_class read class for data store + @param write_class write class for data store + @param store_args data store arguments + """ + self.class_write = args['write'] + self.class_read = args['read'] + self.store_args = args['store'] + self.default_plan = args['default'] + self.factory = DataSourceFactory() + self.uid = args['uid'] + + + def register(self,pid): + if pid is None : + pid = self.default_plan + + if self.is_registered(pid) == False: + plan_info = self.__signup(pid) + return self.__update(pid,plan_info) + else: + # + # If the user is already registered for this plan, there is nothing much to do + # @TODO: Consider plan migration functionality {upgrade,downgrade} + # + return None + + def __signup(self,pid): + auid = str(uuid.uuid4()) + headers = {"uid":self.uid,"pid":pid,"auid":json.dumps([auid])} + + url="https://the-phi.com/store/init/monitor" + r = requests.post(url,headers=headers) + + return json.loads(r.text) + + def __update(self,pid,plan_info) : + """ + Once the signup function has been performed, there needs to be some minor updates + To the document notably in terms of the + """ + auid = self.get_key() + args = dict(self.store_args) + args['uid'] = auid + args['dbname'] = pid + store = self.factory.instance(type=self.class_write,args=args) + store.write(label='emails',row=[auid,self.uid]) + plan = {pid:plan_info} + store.write(label='plan',data=plan) + return self.get_info() + #return {"key":auid,"name":pid,"info":plan_info} + def get_info(self): + try: + plan = self.get_active_plan() + + key = self.get_key() + return {"key":key,"name":plan['name'],"info":[plan['metadata']]} + except Exception,e: + print e + return None + def get_key(self) : + store = self.factory.instance(type=self.class_read,args=self.store_args) + id = store.view('federation/uid_map',key=self.uid) + args = dict(self.store_args) + args['uid'] = id + store = self.factory.instance(type=self.class_read,args=args) + document= store.read() + if 'emails' in document and len(document['emails']) > 1 : + + key = [id for id in document['emails'] if '@' not in id] + key = key[len(key)-1] + else: + key = None + return key + + def is_registered(self,pid=None): + store = self.factory.instance(type=self.class_read,args=self.store_args) + id = store.view('federation/uid_map',key=self.uid) + + if id is not None and pid is None : + return id != [] + elif id is None : + return False + else: + # + # We are given a plan, this implies answering the question : + # Is the current user signed-up for the given plan + # + return store.view('plans/active',key=id) != [] + return False + def get_active_plan(self): + store = self.factory.instance(type=self.class_read,args=self.store_args) + id = store.view('federation/uid_map',key=self.uid) + return store.view('plans/active',key=id) + def cancel(self,pid): + pass + def upgrade(self,pid): + pass \ No newline at end of file diff --git a/src/utils/transport.py b/src/utils/transport.py index bace7b3..f56569e 100644 --- a/src/utils/transport.py +++ b/src/utils/transport.py @@ -587,13 +587,32 @@ class CouchdbWriter(Couchdb,Writer): document = self.dbase.get(self.uid) label = params['label'] - row = params['row'] - if label not in document : - document[label] = [] if isinstance(row,list) else {} - if isinstance(document[label],list) : - document[label].append(row) + + if 'row' in params : + row = params['row'] + row_is_list = isinstance(row,list) + if label not in document : + document[label] = row if row_is_list else [row] + + elif isinstance(document[label][0],list) : + document[label].append(row) + else: + document[label] += row else : - document[label] = dict(document[label],**row) + if label not in document : + document[label] = {} + if isinstance(params['data'],object) : + + document[label] = dict(document[label],**params['data']) + else: + document[label] = params['data'] + + # if label not in document : + # document[label] = [] if isinstance(row,list) else {} + # if isinstance(document[label],list): + # document[label].append(row) + # else : + # document[label] = dict(document[label],**row) self.dbase.save_doc(document) def flush(self,**params) :