You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@steve.apache.org by hu...@apache.org on 2015/03/29 14:41:32 UTC

svn commit: r1669903 - in /steve/trunk/pysteve/lib: constants.py election.py voter.py

Author: humbedooh
Date: Sun Mar 29 12:41:31 2015
New Revision: 1669903

URL: http://svn.apache.org/r1669903
Log:
have election and voter use the new db backend files

Modified:
    steve/trunk/pysteve/lib/constants.py
    steve/trunk/pysteve/lib/election.py
    steve/trunk/pysteve/lib/voter.py

Modified: steve/trunk/pysteve/lib/constants.py
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/lib/constants.py?rev=1669903&r1=1669902&r2=1669903&view=diff
==============================================================================
--- steve/trunk/pysteve/lib/constants.py (original)
+++ steve/trunk/pysteve/lib/constants.py Sun Mar 29 12:41:31 2015
@@ -15,11 +15,17 @@
 # limitations under the License.
 #
 
+
 VOTE_TYPES = (
     
 )
 
+DB_TYPES = (
+    
+)
+
 def appendVote(*types):
+    """ Append a new type of voting to the list"""
     global VOTE_TYPES
     for t in types:
         found = False
@@ -30,6 +36,33 @@ def appendVote(*types):
         if not found:
             VOTE_TYPES += (t,)
         
+def appendBackend(*args):
+    """Append a new database backend"""
+    global DB_TYPES
+    for t in args:
+        found = False
+        for v in DB_TYPES:
+            if v['id'] == t['id']:
+                found = True
+                break
+        if not found:
+            DB_TYPES += (t,)
+            
+def initBackend(config):
+    # Set up DB backend
+    backend = None
+    
+    dbtype = config.get("database", "dbsys")
+    for b in DB_TYPES:
+        if b.get('id') == dbtype:
+            backend = b
+            break
+    
+    if not backend:
+        raise Exception("Unknown database backend: %s" % dbtype)
+    else:
+        backend['init'](config)
+    return backend
 
 # For vote types with N number of seats/spots, this value denotes
 # the max number of useable types to display via the API

Modified: steve/trunk/pysteve/lib/election.py
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/lib/election.py?rev=1669903&r1=1669902&r2=1669903&view=diff
==============================================================================
--- steve/trunk/pysteve/lib/election.py (original)
+++ steve/trunk/pysteve/lib/election.py Sun Mar 29 12:41:31 2015
@@ -23,120 +23,33 @@ from itertools import izip
 
 
 from __main__ import homedir, config
-
-es = None
-
-if config.get("database", "dbsys") == "elasticsearch":
-    from elasticsearch import Elasticsearch
-    es = Elasticsearch([
-                    {
-                        'host': config.get("elasticsearch", "host"),
-                        'port': int(config.get("elasticsearch", "port")),
-                        'url_prefix': config.get("elasticsearch", "uri"),
-                        'use_ssl': False if config.get("elasticsearch", "secure") == "false" else True
-                    },
-                ])
-    if not es.indices.exists("steve"):
-        es.indices.create(index = "steve", body = {
-                "settings": {
-                    "number_of_shards" : 3,
-                    "number_of_replicas" : 1
-                }
-            }
-        )
     
 import constants, voter
 from plugins import *
+from backends import *
+
+
+
+# Set up DB backend
+backend = constants.initBackend(config)
+
 
 def exists(election, *issue):
     "Returns True if an election/issue exists, False otherwise"
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", election)
-        if issue:
-            elpath += "/" + issue[0] + ".json"
-            return os.path.isfile(elpath)
-        else:
-            return os.path.isdir(elpath)
-    elif dbtype == "elasticsearch":
-        doc = "elections"
-        eid = election
-        if issue and issue[0]:
-            doc = "issues"
-            eid = hashlib.sha224(election + "/" + issue[0]).hexdigest()
-        try:
-            res = es.exists(index="steve", doc_type=doc, id=eid)
-            if res:
-                return True
-            else:
-                return False
-        except:
-            return False # ES Transport error, assume no such issue
+    return backend['document_exists'](election, *issue)
 
 def getBasedata(election, hideHash=False):
     "Get base data from an election"
-    
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", election)
-        if os.path.isdir(elpath):
-            with open(elpath + "/basedata.json", "r") as f:
-                data = f.read()
-                f.close()
-                basedata = json.loads(data)
-                if hideHash and 'hash' in basedata:
-                    del basedata['hash']
-                basedata['id'] = election
-                return basedata
-    elif dbtype == "elasticsearch":
-        res = es.get(index="steve", doc_type="elections", id=election)
-        if res:
-            return res['_source']
-    return None
+    return backend['get_basedata'](election)
 
 def close(election, reopen = False):
     "Mark an election as closed"
-    dbtype = config.get("database", "dbsys")
-    if exists(election):
-        if dbtype == "file":
-            elpath = os.path.join(homedir, "issues", election)
-            basedata = getBasedata(election)
-            if reopen:
-                basedata['closed'] = False
-            else:
-                basedata['closed'] = True
-            with open(elpath + "/basedata.json", "w") as f:
-                f.write(json.dumps(basedata))
-                f.close()
-        elif dbtype == "elasticsearch":
-            basedata = getBasedata(election)
-            if reopen:
-                basedata['closed'] = False
-            else:
-                basedata['closed'] = True
-            es.index(index="steve", doc_type="elections", id=election, body = basedata )
-        
+    backend['election_close'](election, reopen)
+    
 
 def getIssue(electionID, issueID):
     "Get JSON data from an issue"
-    issuedata = None
-    ihash = ""
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json"
-        if os.path.isfile(issuepath):
-            
-            with open(issuepath, "r") as f:
-                data = f.read()
-                ihash = hashlib.sha224(data).hexdigest()
-                f.close()
-                issuedata = json.loads(data)
-    elif dbtype == "elasticsearch":
-        iid = hashlib.sha224(electionID + "/" + issueID).hexdigest()
-        res = es.get(index="steve", doc_type="issues", id=iid)
-        if res:
-            issuedata = res['_source']
-            ihash = hashlib.sha224(json.dumps(issuedata)).hexdigest()
+    issuedata, ihash = backend['issue_get'](electionID, issueID)
     if issuedata:
         issuedata['hash'] = ihash
         issuedata['id'] = issueID
@@ -154,150 +67,51 @@ def getIssue(electionID, issueID):
 
 def getVotes(electionID, issueID):
     "Read votes from the vote file"
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json.votes"
-        issuedata = {}
-        if os.path.isfile(issuepath):
-            with open(issuepath, "r") as f:
-                data = f.read()
-                f.close()
-                issuedata = json.loads(data)
-        return issuedata
-    elif dbtype == "elasticsearch":
-        res = es.search(index="steve", doc_type="votes", q = "election:%s AND issue:%s" % (electionID, issueID), size = 9999999)
-        results = len(res['hits']['hits'])
-        if results > 0:
-            votes = {}
-            for entry in res['hits']['hits']:
-                votes[entry['_source']['key']] = entry['_source']['data']['vote']
-            return votes
-    return {}
-
-
+    return backend['votes_get'](electionID, issueID)
 
 def getVotesRaw(electionID, issueID):
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json.votes"
-        if os.path.isfile(issuepath):
-            with open(issuepath, "r") as f:
-                votes = json.loads(f.read())
-                f.close()
-                return votes
-    elif dbtype == "elasticsearch":
-        res = es.search(index="steve", doc_type="votes", q = "election:%s AND issue:%s" % (electionID, issueID), size = 9999999)
-        results = len(res['hits']['hits'])
-        if results > 0:
-            votes = {}
-            for entry in res['hits']['hits']:
-                votes[entry['_source']['key']] = entry['_source']['data']
-            return votes
-    return {}
+    return backend['votes_get_raw'](electionID, issueID)
 
 
 def createElection(eid, title, owner, monitors, starts, ends, isopen):
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", eid)
-        os.mkdir(elpath)
-        with open(elpath  + "/basedata.json", "w") as f:
-            f.write(json.dumps({
-                'title': title,
-                'owner': owner,
-                'monitors': monitors,
-                'starts': starts,
-                'ends': ends,
-                'hash': hashlib.sha512("%f-stv-%s" % (time.time(), os.environ['REMOTE_ADDR'] if 'REMOTE_ADDR' in os.environ else random.randint(1,99999999999))).hexdigest(),
-                'open': isopen
-            }))
-            f.close()
-        with open(elpath  + "/voters.json", "w") as f:
-            f.write("{}")
-            f.close()
-    elif dbtype == "elasticsearch":
-        es.index(index="steve", doc_type="elections", id=eid, body =
-            {
-                'id': eid,
-                'title': title,
-                'owner': owner,
-                'monitors': monitors,
-                'starts': starts,
-                'ends': ends,
-                'hash': hashlib.sha512("%f-stv-%s" % (time.time(), os.environ['REMOTE_ADDR'] if 'REMOTE_ADDR' in os.environ else random.randint(1,99999999999))).hexdigest(),
-                'open': isopen
-            }
-        );
+    basedata =  {
+            'id': eid,
+            'title': title,
+            'owner': owner,
+            'monitors': monitors,
+            'starts': starts,
+            'ends': ends,
+            'hash': hashlib.sha512("%f-stv-%s" % (time.time(), os.environ['REMOTE_ADDR'] if 'REMOTE_ADDR' in os.environ else random.randint(1,99999999999))).hexdigest(),
+            'open': isopen
+        }
+    backend['election_create'](eid, basedata)
+    
 
 def updateElection(electionID, basedata):
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", electionID)
-        with open(elpath  + "/basedata.json", "w") as f:
-            f.write(json.dumps(basedata))
-            f.close()
-    elif dbtype == "elasticsearch":
-        es.index(index = "steve", doc_type = "elections", id=electionID, body = basedata)
+    backend['election_update'](electionID, basedata)
+
 
 def updateIssue(electionID, issueID, issueData):
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json"
-        with open(issuepath, "w") as f:
-            f.write(json.dumps(issueData))
-            f.close()
-    elif dbtype == "elasticsearch":
-        es.index(index = "steve", doc_type = "issues", id=hashlib.sha224(electionID + "/" + issueID).hexdigest(), body = issueData)
+    backend['issue_update'](electionID, issueID, issueData)
 
 
 def listIssues(election):
     "List all issues in an election"
-    issues = []
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", election)
-        if os.path.isdir(elpath):
-            issues = [f.strip(".json") for f in os.listdir(elpath) if os.path.isfile(os.path.join(elpath, f)) and f != "basedata.json" and f != "voters.json" and f.endswith(".json")]
-    elif dbtype == "elasticsearch":
-        try:
-            res = es.search(index="steve", doc_type="issues", sort = "id", q = "election:%s" % election, size = 999)
-            results = len(res['hits']['hits'])
-            if results > 0:
-                for entry in res['hits']['hits']:
-                    issues.append(entry['_source']['id'])
-        except:
-            pass # THIS IS OKAY! ES WILL FAIL IF THERE ARE NO ISSUES YET
-    return issues
+    return backend['issue_list'](election)
 
 def listElections():
     "List all elections"
-    elections = []
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        path = os.path.join(homedir, "issues")
-        if os.path.isdir(path):
-            elections = [f for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))]
-    elif dbtype == "elasticsearch":
-        try:
-            res = es.search(index="steve", doc_type="elections", sort = "id", q = "*", size = 99999)
-            results = len(res['hits']['hits'])
-            if results > 0:
-                for entry in res['hits']['hits']:
-                    source  = entry['_source']
-                    elections.append(source['id'])
-        except Exception as err:
-            pass # THIS IS OKAY! On initial setup, this WILL fail until an election has been created
-    return elections
+    return backend['election_list']()
+
 
 def getVoteType(issue):
     for voteType in constants.VOTE_TYPES:
         if voteType['key'] == issue['type']:
             return voteType
-    return {}
+    return None
 
 def vote(electionID, issueID, voterID, vote):
     "Casts a vote on an issue"
-    votes = {}
     basedata = getBasedata(electionID)
     issueData = getIssue(electionID, issueID)
     if basedata and issueData:
@@ -307,48 +121,16 @@ def vote(electionID, issueID, voterID, v
         voteType = getVoteType(issueData)
         if voteType.get('vote_func'):
             # This will/should raise an exception if the vote is invalid
-            voteType['vote_func'](basedata, issueID, voterID, vote)
+            uid = voter.get(electionID, basedata, voterID)
+            voteType['vote_func'](basedata, issueID, voterID, vote, uid)
             
-        dbtype = config.get("database", "dbsys")
-        if dbtype == "file":
-            issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json"
-            if os.path.isfile(issuepath + ".votes"):
-                with open(issuepath + ".votes", "r") as f:
-                    votes = json.loads(f.read())
-                    f.close()
-            votes[voterID] = {
-                'vote': vote,
-                'timestamp': time.time()
-            }
-            with open(issuepath + ".votes", "w") as f:
-                f.write(json.dumps(votes))
-                f.close()
+        backend['vote'](electionID, issueID, voterID, vote)
         
-            # LURK on who voted :O :O :O
-            if config.has_option("general", "lurk") and config.get("general", "lurk") == "yes":
-                email = voter.get(electionID, basedata, voterID)
-                lurks = {}
-                lurkpath = os.path.join(homedir, "issues", electionID, "who.voted")
-                if os.path.isfile(lurkpath):
-                    with open(lurkpath, "r") as f:
-                        lurks = json.loads(f.read())
-                        f.close()
-                lurks[email] = True
-                with open(lurkpath, "w") as f:
-                    f.write(json.dumps(lurks))
-                    f.close()
-        elif dbtype == "elasticsearch":
-            es.index(index="steve", doc_type="votes", id=votehash, body =
-                {
-                    'issue': issueID,
-                    'election': electionID,
-                    'key': votehash,
-                    'data': {
-                        'timestamp': time.time(),
-                        'vote': vote
-                    }
-                }
-            );
+        # LURK on who voted :O :O :O
+       # if config.has_option("general", "lurk") and config.get("general", "lurk") == "yes":
+            #email = voter.get(electionID, basedata, voterID)
+          #  backend['lurk'](electionID, email)
+       
         return votehash
     else:
         raise Exception("No such election")
@@ -375,17 +157,8 @@ def tally(votes, issue):
 def deleteIssue(electionID, issueID):
     "Deletes an issue if it exists"
     
-    if exists(electionID):
-        dbtype = config.get("database", "dbsys")
-        if dbtype == "file":
-            issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json"
-            if os.path.isfile(issuepath):
-                os.unlink(issuepath)
-            if os.path.isfile(issuepath + ".votes"):
-                os.unlink(issuepath + ".votes")
-        elif dbtype == "elasticsearch":
-            es.delete(index="steve", doc_type="votes", id=hashlib.sha224(electionID + "/" + issueID).hexdigest());
-        return True
+    if exists(electionID, issueID):
+        backend['issue_delete'](electionID, issueID)
     else:
         raise Exception("No such election")
 
@@ -406,16 +179,4 @@ def getHash(electionID):
     return tothash, "\n".join(output)
 
 def createIssue(electionID, issueID, data):
-    if not exists(electionID, issueID):
-        dbtype = config.get("database", "dbsys")
-        if dbtype == "file":
-            issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json"
-            with open(issuepath, "w") as f:
-                f.write(json.dumps(data))
-                f.close()
-        elif dbtype == "elasticsearch":
-            data['election'] = electionID
-            data['id'] = issueID
-            es.index(index="steve", doc_type="issues", id=hashlib.sha224(electionID + "/" + issueID).hexdigest(), body = data);
-    else:
-        raise Exception("Issue already exists!")
\ No newline at end of file
+    backend['issue_create'](electionID, issueID, data)
\ No newline at end of file

Modified: steve/trunk/pysteve/lib/voter.py
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/lib/voter.py?rev=1669903&r1=1669902&r2=1669903&view=diff
==============================================================================
--- steve/trunk/pysteve/lib/voter.py (original)
+++ steve/trunk/pysteve/lib/voter.py Sun Mar 29 12:41:31 2015
@@ -23,113 +23,29 @@ from email.mime.text import MIMEText
 from email.mime.multipart import MIMEMultipart
 from smtplib import SMTPException
 
-es = None
-
-if config.get("database", "dbsys") == "elasticsearch":
-    from elasticsearch import Elasticsearch
-    es = Elasticsearch([
-                    {
-                        'host': config.get("elasticsearch", "host"),
-                        'port': int(config.get("elasticsearch", "port")),
-                        'url_prefix': config.get("elasticsearch", "uri"),
-                        'use_ssl': False if config.get("elasticsearch", "secure") == "false" else True
-                    },
-                ])
-    if not es.indices.exists("steve"):
-        es.indices.create(index = "steve", body = {
-                "settings": {
-                    "number_of_shards" : 3,
-                    "number_of_replicas" : 1
-                }
-            }
-        )
-    
+from lib import constants, election
 
+backend = constants.initBackend(config)
 
 def get(election, basedata, uid):
     xhash = hashlib.sha512(basedata['hash'] + uid).hexdigest()
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", election)
-        with open(elpath + "/voters.json", "r") as f:
-            voters = json.loads(f.read())
-            f.close()
-            for voter in voters:
-                if voters[voter] == xhash:
-                    return voter
-    elif dbtype == "elasticsearch":
-        try:
-            res = es.search(index="steve", doc_type="voters", q = "election:%s" % election, size = 999999)
-            results = len(res['hits']['hits'])
-            if results > 0:
-                for entry in res['hits']['hits']:
-                    voter = entry['_source']
-                    if voter['hash'] == xhash:
-                        return voter['uid']
-        except:
-            return False # ES Error, probably not seeded the voters doc yet
-    return None
+    return backend['voter_get_uid'](election, xhash)
+    
         
 def add(election, basedata, PID):
     uid = hashlib.sha224("%s%s%s%s" % (PID, basedata['hash'], time.time(), random.randint(1,99999999))).hexdigest()
     xhash = hashlib.sha512(basedata['hash'] + uid).hexdigest()
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", election)
-        with open(elpath + "/voters.json", "r") as f:
-            voters = json.loads(f.read())
-            f.close()
-        voters[PID] = xhash
-        with open(elpath + "/voters.json", "w") as f:
-            f.write(json.dumps(voters))
-            f.close()
-    elif dbtype == "elasticsearch":
-        eid = hashlib.sha224(election + ":" + PID).hexdigest()
-        es.index(index="steve", doc_type="voters", id=eid, body = {
-            'election': election,
-            'hash': xhash,
-            'uid': PID
-            }
-        )
+    backend['voter_add'](election, PID, xhash)
     return uid, xhash
-
+    
 def remove(election, basedata, UID):
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        elpath = os.path.join(homedir, "issues", election)
-        with open(elpath + "/voters.json", "r") as f:
-            voters = json.loads(f.read())
-            f.close()
-        if UID in voters:
-            del voters[UID]
-        with open(elpath + "/voters.json", "w") as f:
-            f.write(json.dumps(voters))
-            f.close()
-    elif dbtype == "elasticsearch":
-        eid = hashlib.sha224(election + ":" + UID).hexdigest()
-        es.delete(index="steve", doc_type="voters", id=votehash);
+    backend['voter_remove'](election, UID)
+    
 
 def hasVoted(election, issue, uid):
     issue = issue.strip(".json")
-    dbtype = config.get("database", "dbsys")
-    if dbtype == "file":
-        path = os.path.join(homedir, "issues", election, issue)
-        votes = {}
-        if os.path.isfile(path + ".json.votes"):
-            with open(path + ".json.votes", "r") as f:
-                votes = json.loads(f.read())
-                f.close()
-        return True if uid in votes else False
-    elif dbtype == "elasticsearch":
-        eid = hashlib.sha224(election + ":" + uid).hexdigest()
-        try:
-            res = es.search(index="steve", doc_type="voters", sort = "id", q = "_id:%s" % eid, size = 1)
-            results = len(res['hits']['hits'])
-            if results > 0:
-                return True
-        except:
-            return False
-    return False
+    return backend['voter_has_voted'](election, issue, uid)
+
 
 def email(rcpt, subject, message):
     sender = config.get("email", "sender")