From 102997efc8118b5bde5189da45a38d48e05e17a0 Mon Sep 17 00:00:00 2001 From: iou1name Date: Wed, 18 Jul 2018 19:09:54 -0400 Subject: [PATCH] refactor poll_votes database queries --- anonkun.py | 10 +-------- anonkun.sql | 4 +++- database.py | 49 ++++++++++++++++++++++++-------------------- events.py | 13 +++++++++++- templates/quest.html | 12 +++++++++-- views.py | 6 ++++++ 6 files changed, 59 insertions(+), 35 deletions(-) diff --git a/anonkun.py b/anonkun.py index cee82cb..ab78cc1 100644 --- a/anonkun.py +++ b/anonkun.py @@ -59,7 +59,7 @@ app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 app.config['SESSION_TYPE'] = 'filesystem' app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True -app.jinja_env.undefined = "StrictUndefined" +#app.jinja_env.undefined = "StrictUndefined" Session(app) socketio.init_app(app) paranoid = Paranoid(app) @@ -99,14 +99,6 @@ def get_dice_challenge(post_id): 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 def minify(res): """ diff --git a/anonkun.sql b/anonkun.sql index dc84b12..2fa0aa0 100644 --- a/anonkun.sql +++ b/anonkun.sql @@ -67,6 +67,7 @@ CREATE TABLE `polls` ( CREATE TABLE `poll_options` ( `option_id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT, `post_id` MEDIUMINT UNSIGNED NOT NULL, + `quest_id` SMALLINT UNSIGNED NOT NULL, `option_text` VARCHAR(200) NOT NULL, PRIMARY KEY (`option_id`), FOREIGN KEY (`post_id`) REFERENCES `polls`(`post_id`) @@ -75,5 +76,6 @@ CREATE TABLE `poll_options` ( CREATE TABLE `poll_votes` ( `option_id` MEDIUMINT UNSIGNED 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; diff --git a/database.py b/database.py index a81ed57..9a33738 100644 --- a/database.py +++ b/database.py @@ -296,39 +296,44 @@ def insert_poll_option(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.""" - sql = "SELECT * FROM `poll_options` WHERE " - if quest_id: - sql += "`quest_id` = %s" - ins = (quest_id,) - elif post_id: - sql += "`post_id` = %s" - ins = (post_id,) - else: - return - data = _DB.execute(sql, ins).fetchall() + data = _DB.execute( + "SELECT DISTINCT " \ + + "`poll_options`.* FROM `poll_options`, `quest_data` " \ + + "WHERE `quest_data`.`post_id` = `poll_options`.`post_id` " \ + + "AND `quest_data`.`quest_id` = %s", + (quest_id,)).fetchall() return data def insert_poll_vote(option_id, ip): """Inserts a new vote for a poll option.""" - res = _DB.execute( - "INSERT ") + try: + _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.""" - pass + _DB.execute( + "DELETE FROM `poll_votes` " \ + "WHERE `option_id` = %s AND `ip_address` = %s", + (option_id, ip)) def get_poll_votes(quest_id): - pass - - -def get_num_votes(option_id): - """Returns the number of votes for an option.""" + """Gets all poll votes for the given quest_id.""" data = _DB.execute( - "SELECT COUNT(`ip_address`) FROM `poll_votes` WHERE `option_id` = %s", - (option_id,)).fetchone()[0] + "SELECT `poll_votes`.* FROM `poll_votes` LEFT JOIN `poll_options` " \ + + "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 diff --git a/events.py b/events.py index bce7460..cb23f1f 100644 --- a/events.py +++ b/events.py @@ -314,7 +314,18 @@ def vote(data): """ Called when a user changes their vote on a poll. """ - print(data) room = data.get("room") option_id = data.get("option_id") 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) diff --git a/templates/quest.html b/templates/quest.html index f1e74f8..68f1477 100644 --- a/templates/quest.html +++ b/templates/quest.html @@ -90,6 +90,14 @@ 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'); mtarea.addEventListener('keypress', function(event) { if (event.key == 'Enter' && !event.shiftKey) { @@ -252,13 +260,13 @@ {% for option in options[quest_post[0]] %} - + {{ option[2] }} - {{ option[0]|num_votes }} + {{ poll_votes[option[0]]|length }} {% endfor %} diff --git a/views.py b/views.py index 5c9b9da..ccef03c 100644 --- a/views.py +++ b/views.py @@ -56,6 +56,7 @@ def quest(quest_title): quest_title = data[1] owner_id = data[3] open_post_id = data[4] + ip_address = request.remote_addr quest_posts = db.get_quest_data(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] 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) return render_template('quest.html', **locals())