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")