Compare commits

...

1 Commits

Author SHA1 Message Date
102997efc8 refactor poll_votes database queries 2018-07-18 19:35:35 -04:00
6 changed files with 59 additions and 35 deletions

View File

@ -59,7 +59,7 @@ app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
app.config['SESSION_TYPE'] = 'filesystem' app.config['SESSION_TYPE'] = 'filesystem'
app.jinja_env.trim_blocks = True app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True app.jinja_env.lstrip_blocks = True
app.jinja_env.undefined = "StrictUndefined" #app.jinja_env.undefined = "StrictUndefined"
Session(app) Session(app)
socketio.init_app(app) socketio.init_app(app)
paranoid = Paranoid(app) paranoid = Paranoid(app)
@ -99,14 +99,6 @@ def get_dice_challenge(post_id):
return db.get_dice_call(post_id)[3] return db.get_dice_call(post_id)[3]
@app.template_filter("num_votes")
def num_votes(option_id):
"""
Returns the number of IPs who voted for this option.
"""
return db.get_num_votes(option_id)
@app.after_request @app.after_request
def minify(res): def minify(res):
""" """

View File

@ -67,6 +67,7 @@ CREATE TABLE `polls` (
CREATE TABLE `poll_options` ( CREATE TABLE `poll_options` (
`option_id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT, `option_id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
`post_id` MEDIUMINT UNSIGNED NOT NULL, `post_id` MEDIUMINT UNSIGNED NOT NULL,
`quest_id` SMALLINT UNSIGNED NOT NULL,
`option_text` VARCHAR(200) NOT NULL, `option_text` VARCHAR(200) NOT NULL,
PRIMARY KEY (`option_id`), PRIMARY KEY (`option_id`),
FOREIGN KEY (`post_id`) REFERENCES `polls`(`post_id`) FOREIGN KEY (`post_id`) REFERENCES `polls`(`post_id`)
@ -75,5 +76,6 @@ CREATE TABLE `poll_options` (
CREATE TABLE `poll_votes` ( CREATE TABLE `poll_votes` (
`option_id` MEDIUMINT UNSIGNED NOT NULL, `option_id` MEDIUMINT UNSIGNED NOT NULL,
`ip_address` VARCHAR(32) NOT NULL, `ip_address` VARCHAR(32) NOT NULL,
FOREIGN KEY (`option_id`) REFERENCES `poll_options`(`option_id`) FOREIGN KEY (`option_id`) REFERENCES `poll_options`(`option_id`),
UNIQUE (`option_id`, `ip_address`)
) ENGINE=InnoDB CHARSET utf8mb4; ) ENGINE=InnoDB CHARSET utf8mb4;

View File

@ -296,39 +296,44 @@ def insert_poll_option(post_id, option_text):
(post_id, option_text)) (post_id, option_text))
def get_poll_options(quest_id=None, post_id=None): def get_poll_options(quest_id):
"""Gets all relevent poll options for a given quest or post.""" """Gets all relevent poll options for a given quest or post."""
sql = "SELECT * FROM `poll_options` WHERE " data = _DB.execute(
if quest_id: "SELECT DISTINCT " \
sql += "`quest_id` = %s" + "`poll_options`.* FROM `poll_options`, `quest_data` " \
ins = (quest_id,) + "WHERE `quest_data`.`post_id` = `poll_options`.`post_id` " \
elif post_id: + "AND `quest_data`.`quest_id` = %s",
sql += "`post_id` = %s" (quest_id,)).fetchall()
ins = (post_id,)
else:
return
data = _DB.execute(sql, ins).fetchall()
return data return data
def insert_poll_vote(option_id, ip): def insert_poll_vote(option_id, ip):
"""Inserts a new vote for a poll option.""" """Inserts a new vote for a poll option."""
res = _DB.execute( try:
"INSERT ") _DB.execute(
"INSERT INTO `poll_votes` " \
"(`option_id`, `ip_address`) VALUES (%s, %s)",
(option_id, ip))
except MySQLdb.IntegrityError:
# this ip has already voted for this option
return
def insert_poll_vote(option_id, ip): def remove_poll_vote(option_id, ip):
"""Removes a vote from a poll.""" """Removes a vote from a poll."""
pass _DB.execute(
"DELETE FROM `poll_votes` " \
"WHERE `option_id` = %s AND `ip_address` = %s",
(option_id, ip))
def get_poll_votes(quest_id): def get_poll_votes(quest_id):
pass """Gets all poll votes for the given quest_id."""
def get_num_votes(option_id):
"""Returns the number of votes for an option."""
data = _DB.execute( data = _DB.execute(
"SELECT COUNT(`ip_address`) FROM `poll_votes` WHERE `option_id` = %s", "SELECT `poll_votes`.* FROM `poll_votes` LEFT JOIN `poll_options` " \
(option_id,)).fetchone()[0] + "ON `poll_votes`.`option_id` = `poll_options`.`option_id` " \
+ "LEFT JOIN `quest_data` " \
+ "ON `poll_options`.`post_id`=`quest_data`.`post_id` " \
+ "WHERE `quest_data`.`quest_id` = %s",
(quest_id,)).fetchall()
return data return data

View File

@ -314,7 +314,18 @@ def vote(data):
""" """
Called when a user changes their vote on a poll. Called when a user changes their vote on a poll.
""" """
print(data)
room = data.get("room") room = data.get("room")
option_id = data.get("option_id") option_id = data.get("option_id")
polarity = data.get("polarity") polarity = data.get("polarity")
#ip_address = request.remote_addr
ip_address = request.headers.get("X-Real-Ip")
if polarity:
db.insert_poll_vote(option_id, ip_address)
else:
db.remove_poll_vote(option_id, ip_address)
data = {}
data["option_id"] = option_id
data["polarity"] = polarity
emit("vote", data, room=room)

View File

@ -90,6 +90,14 @@
table.getElementsByTagName("col")[0].style.visibility = ''; table.getElementsByTagName("col")[0].style.visibility = '';
} }
}); });
socket.on('vote', function(data) {
let row = document.getElementById('optionRow-' + data.option_id);
if (data.polarity) {
row.cells[2].textContent = Number(row.cells[2].textContent) + 1;
} else {
row.cells[2].textContent = Number(row.cells[2].textContent) - 1;
}
});
let mtarea = document.getElementById('messageTextArea'); let mtarea = document.getElementById('messageTextArea');
mtarea.addEventListener('keypress', function(event) { mtarea.addEventListener('keypress', function(event) {
if (event.key == 'Enter' && !event.shiftKey) { if (event.key == 'Enter' && !event.shiftKey) {
@ -252,13 +260,13 @@
<col/> <col/>
<col/> <col/>
{% for option in options[quest_post[0]] %} {% for option in options[quest_post[0]] %}
<tr> <tr id="optionRow-{{ option[0] }}">
<td class="pollCheckBox"> <td class="pollCheckBox">
<input type="checkbox" id="pollInput-{{ option[0] }}" onchange="pollVote({{ option[0] }})"/> <input type="checkbox" id="pollInput-{{ option[0] }}" onchange="pollVote({{ option[0] }})"/>
<label for="pollInput-{{ option[0] }}"></label> <label for="pollInput-{{ option[0] }}"></label>
</td> </td>
<td class="option_text">{{ option[2] }}</td> <td class="option_text">{{ option[2] }}</td>
<td class="optionVotes">{{ option[0]|num_votes }}</td> <td class="optionVotes">{{ poll_votes[option[0]]|length }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -56,6 +56,7 @@ def quest(quest_title):
quest_title = data[1] quest_title = data[1]
owner_id = data[3] owner_id = data[3]
open_post_id = data[4] open_post_id = data[4]
ip_address = request.remote_addr
quest_posts = db.get_quest_data(quest_id) quest_posts = db.get_quest_data(quest_id)
dice_rolls_raw = db.get_dice_rolls(quest_id) dice_rolls_raw = db.get_dice_rolls(quest_id)
@ -68,6 +69,11 @@ def quest(quest_title):
_ = [options[opt[1]].append(opt) for opt in options_raw] _ = [options[opt[1]].append(opt) for opt in options_raw]
del options_raw del options_raw
poll_votes_raw = db.get_poll_votes(quest_id)
poll_votes = {vote[0]: [] for vote in poll_votes_raw}
_ = [poll_votes[vote[0]].append(vote[1]) for vote in poll_votes_raw]
del poll_votes_raw
messages = db.get_chat_messages(quest_id) messages = db.get_chat_messages(quest_id)
return render_template('quest.html', **locals()) return render_template('quest.html', **locals())