Skip to content
This repository was archived by the owner on Feb 3, 2024. It is now read-only.

Commit 6cfc77f

Browse files
Vivian Nowka-KeaneNicholas V Mercadante
authored andcommitted
Initial working upvote/downvotes (#43)
1 parent 85990e3 commit 6cfc77f

File tree

8 files changed

+486
-5
lines changed

8 files changed

+486
-5
lines changed

quotefault/__init__.py

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from flask import Flask, render_template, request, flash, session, make_response
99
from flask_pyoidc.flask_pyoidc import OIDCAuthentication
1010
from flask_sqlalchemy import SQLAlchemy
11+
from sqlalchemy import func
1112

1213
app = Flask(__name__)
1314
# look for a config file to associate with a db/port/ip/servername
@@ -52,6 +53,24 @@ def __init__(self, submitter, quote, speaker):
5253
self.speaker = speaker
5354

5455

56+
class Vote(db.Model):
57+
id = db.Column(db.Integer, primary_key=True, nullable=False)
58+
quote_id = db.Column(db.ForeignKey("quote.id"))
59+
voter = db.Column(db.String(200), nullable=False)
60+
direction = db.Column(db.Integer, nullable=False)
61+
updated_time = db.Column(db.DateTime, nullable=False)
62+
63+
quote = db.relationship(Quote)
64+
test = db.UniqueConstraint("quote_id", "voter")
65+
66+
# initialize a row for the Vote table
67+
def __init__(self, quote_id, voter, direction):
68+
self.quote_id = quote_id
69+
self.voter = voter
70+
self.direction = direction
71+
self.updated_time = datetime.now()
72+
73+
5574
def get_metadata():
5675
uuid = str(session["userinfo"].get("sub", ""))
5776
uid = str(session["userinfo"].get("preferred_username", ""))
@@ -89,6 +108,30 @@ def settings():
89108
return render_template('bootstrap/settings.html', metadata=metadata)
90109

91110

111+
@app.route('/vote', methods=['POST'])
112+
@auth.oidc_auth
113+
def make_vote():
114+
# submitter will grab UN from OIDC when linked to it
115+
submitter = session['userinfo'].get('preferred_username', '')
116+
117+
quote = request.form['quote_id']
118+
direction = request.form['direction']
119+
120+
existing_vote = Vote.query.filter_by(voter=submitter, quote_id=quote).first()
121+
if existing_vote is None:
122+
vote = Vote(quote, submitter, direction)
123+
db.session.add(vote)
124+
db.session.commit()
125+
return '200'
126+
elif existing_vote.direction != direction:
127+
existing_vote.direction = direction
128+
existing_vote.updated_time = datetime.now()
129+
db.session.commit()
130+
return '200'
131+
else:
132+
return '201'
133+
134+
92135
@app.route('/settings', methods=['POST'])
93136
@auth.oidc_auth
94137
def update_settings():
@@ -164,7 +207,7 @@ def submit():
164207
def get():
165208
metadata = get_metadata()
166209
metadata['submitter'] = request.args.get('submitter') # get submitter from url query string
167-
metadata['speaker'] = request.args.get('speaker') # get submitter from url query string
210+
metadata['speaker'] = request.args.get('speaker') # get speaker from url query string
168211

169212
if metadata['speaker'] is not None and metadata['submitter'] is not None:
170213
quotes = Quote.query.order_by(Quote.quote_time.desc()).filter(Quote.submitter == metadata['submitter'],
@@ -174,19 +217,27 @@ def get():
174217
elif metadata['speaker'] is not None:
175218
quotes = Quote.query.order_by(Quote.quote_time.desc()).filter(Quote.speaker == metadata['speaker']).all()
176219
else:
177-
quotes = Quote.query.order_by(Quote.quote_time.desc()).limit(20).all() # collect all quote rows in the Quote db
220+
# quotes = Quote.query.order_by(Quote.quote_time.desc()).limit(20).all()
221+
222+
# returns tuples with a quote and its net vote value
223+
quotes = db.session.query(Quote, func.sum(Vote.direction).label('votes')).outerjoin(Vote).group_by(Quote).order_by(
224+
Quote.quote_time.desc()).limit(20).all()
225+
226+
user_votes = db.session.query(Vote).filter(Vote.voter == metadata['submitter']).all()
178227

179228
if request.cookies.get('flag'):
180229
return render_template(
181230
'flag/storage.html',
182231
quotes=quotes,
183-
metadata=metadata
232+
metadata=metadata,
233+
user_votes=user_votes
184234
)
185235
else:
186236
return render_template(
187237
'bootstrap/storage.html',
188238
quotes=quotes,
189-
metadata=metadata
239+
metadata=metadata,
240+
user_votes=user_votes
190241
)
191242

192243

quotefault/static/css/quotefaultcss.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ body{
3636
.contentContainer a:hover{
3737
color: #d1d6d6;
3838
}
39+
40+

quotefault/static/css/styles.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,9 @@ div.version{
313313
#get_more {
314314
width: 100%;
315315
}
316+
317+
.upvote-meta-stackoverflow{
318+
text-align: right;
319+
float: right;
320+
justify-content: right;
321+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
div.upvote {
2+
text-align: center;
3+
}
4+
5+
div.upvote a.upvote-enabled {
6+
cursor: pointer;
7+
}
8+
9+
div.upvote a {
10+
color: transparent;
11+
background-image: url('images/sprites-stackoverflow.png?v=1');
12+
background-repeat: no-repeat;
13+
overflow: hidden;
14+
display: block;
15+
margin: 0 auto;
16+
width: 41px;
17+
height: 25px;
18+
}
19+
20+
div.upvote span.count {
21+
display: block;
22+
font-size: 24px;
23+
font-family: Arial, Liberation, Sans, DejaVu Sans, sans-serif;
24+
color: #555;
25+
text-align: center;
26+
line-height: 1;
27+
}
28+
29+
div.upvote a.upvote {
30+
background-position: 0px -265px;
31+
}
32+
33+
div.upvote a.upvote.upvote-on {
34+
background-position: 0px -230px;
35+
}
36+
37+
div.upvote a.downvote {
38+
background-position: 0px -300px;
39+
}
40+
41+
div.upvote a.downvote.downvote-on {
42+
background-position: 0px -330px;
43+
}
44+
45+
div.upvote a.star {
46+
width: 33px;
47+
height: 31px;
48+
background-position: 0px -150px;
49+
}
50+
51+
div.upvote a.star.star-on {
52+
background-position: 0px -190px;
53+
}
54+
55+
div.upvote-serverfault a {
56+
background-image: url('images/sprites-serverfault.png?v=1');
57+
}
58+
59+
div.upvote-meta-stackoverflow a {
60+
background-image: url('images/sprites-meta-stackoverflow.png?v=1');
61+
}
62+
63+
div.upvote-superuser a {
64+
background-image: url('images/sprites-superuser.png?v=1');
65+
}
66+
67+
div.upvote-unix a {
68+
background-image: url('images/sprites-unix.png?v=1');
69+
width: 42px;
70+
height: 27px;
71+
}
72+
73+
div.upvote-unix a.upvote {
74+
background-position: 0px -237px;
75+
}
76+
77+
div.upvote-unix a.upvote.upvote-on {
78+
background-position: 0px -198px;
79+
}
80+
81+
div.upvote-unix a.downvote {
82+
background-position: 0px -281px;
83+
}
84+
85+
div.upvote-unix a.downvote.downvote-on {
86+
background-position: 0px -319px;
87+
}
88+
89+
div.upvote-unix a.star {
90+
width: 42px;
91+
height: 30px;
92+
background-position: 0px -126px;
93+
}
94+
95+
div.upvote-unix a.star.star-on {
96+
background-position: 0px -164px;
97+
}
98+
99+
div.upvote-unix span.count {
100+
color: #333;
101+
line-height: 15px;
102+
padding: 9px 0;
103+
font-family: "DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",Courier,Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter",monospace;
104+
text-shadow: 1px 1px 0 #ffffff;
105+
font-weight: bold;
106+
margin: 0;
107+
border: 0;
108+
vertical-align: baseline;
109+
}
110+
111+
div.upvote-programmers a {
112+
background-image: url('images/sprites-programmers.png?v=1');
113+
width: 42px;
114+
height: 20px;
115+
}
116+
117+
div.upvote-programmers a.upvote {
118+
background-position: 5px -248px;
119+
}
120+
121+
div.upvote-programmers a.upvote.upvote-on {
122+
background-position: 5px -211px;
123+
}
124+
125+
div.upvote-programmers a.downvote {
126+
background-position: 5px -282px;
127+
}
128+
129+
div.upvote-programmers a.downvote.downvote-on {
130+
background-position: 5px -320px;
131+
}
132+
133+
div.upvote-programmers a.star {
134+
width: 42px;
135+
height: 30px;
136+
background-position: 6px -128px;
137+
}
138+
139+
div.upvote-programmers a.star.star-on {
140+
background-position: 6px -166px;
141+
}
142+
143+
div.upvote-programmers span.count {
144+
color: #333;
145+
line-height: 15px;
146+
padding: 5px 0 7px;
147+
font-size: 20px;
148+
font-weight: bold;
149+
font-family: Tahoma,Geneva,Arial,sans-serif;
150+
}

0 commit comments

Comments
 (0)