Merge pull request #66 from Aevann1/polls

Polls
master
Aevann1 2021-10-06 02:05:15 +02:00 committed by GitHub
commit 4ea8cb58aa
11 changed files with 120 additions and 39 deletions

View File

@ -2,7 +2,8 @@ import re
from urllib.parse import urlencode, urlparse, parse_qs
from flask import *
from sqlalchemy import *
from sqlalchemy.orm import relationship, deferred
from sqlalchemy.orm import relationship, deferred, lazyload
from files.classes.votes import CommentVote
from files.helpers.lazy import lazy
from files.helpers.const import SLURS
from files.__main__ import Base
@ -37,7 +38,7 @@ class Comment(Base):
notifiedto=Column(Integer)
app_id = Column(Integer, ForeignKey("oauth_apps.id"))
oauth_app = relationship("OauthApp", viewonly=True)
upvotes = Column(Integer, default=1)
upvotes = Column(Integer, default=0)
downvotes = Column(Integer, default=0)
body = deferred(Column(String(10000)))
body_html = deferred(Column(String(20000)))
@ -61,6 +62,13 @@ class Comment(Base):
return f"<Comment(id={self.id})>"
def poll_voted(self, v):
if v:
vote = g.db.query(CommentVote).options(lazyload('*')).filter_by(user_id=v.id, comment_id=self.id).first()
if vote: return vote.vote_type
else: return None
else: return None
@property
@lazy
def created_datetime(self):

View File

@ -4,9 +4,9 @@ from sqlalchemy.orm import relationship, deferred
import re, random
from urllib.parse import urlparse
from files.helpers.lazy import lazy
from files.helpers.const import SLURS
from files.helpers.const import SLURS, AUTOPOLLER_ACCOUNT
from files.__main__ import Base
from .flags import *
from .flags import Flag
from os import environ
import time
@ -35,11 +35,8 @@ class Submission(Base):
private = Column(Boolean, default=False)
club = Column(Boolean, default=False)
comment_count = Column(Integer, default=0)
comments = relationship("Comment", primaryjoin="Comment.parent_submission==Submission.id", viewonly=True)
flags = relationship("Flag", lazy="dynamic", viewonly=True)
is_approved = Column(Integer, ForeignKey("users.id"), default=0)
over_18 = Column(Boolean, default=False)
author = relationship("User", primaryjoin="Submission.author_id==User.id")
is_bot = Column(Boolean, default=False)
upvotes = Column(Integer, default=1)
downvotes = Column(Integer, default=0)
@ -52,6 +49,9 @@ class Submission(Base):
ban_reason = Column(String(128))
embed_url = Column(String(256))
comments = relationship("Comment", lazy="dynamic", primaryjoin="Comment.parent_submission==Submission.id", viewonly=True)
flags = relationship("Flag", lazy="dynamic", viewonly=True)
author = relationship("User", primaryjoin="Submission.author_id==User.id")
oauth_app = relationship("OauthApp", viewonly=True)
approved_by = relationship("User", uselist=False, primaryjoin="Submission.is_approved==User.id", viewonly=True)
awards = relationship("AwardRelationship", viewonly=True)
@ -71,6 +71,16 @@ class Submission(Base):
return f"<Submission(id={self.id})>"
@property
@lazy
def options(self):
return self.comments.filter_by(author_id = AUTOPOLLER_ACCOUNT)
@property
@lazy
def created_datetime(self):
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc)))
@property
@lazy
def created_datetime(self):

View File

@ -165,6 +165,7 @@ NOTIFICATIONS_ACCOUNT = 1046
if site == "pcmemes.net": AUTOJANNY_ACCOUNT = 1050
else: AUTOJANNY_ACCOUNT = 2360
LONGPOSTBOT_ACCOUNT = 1832
AUTOPOLLER_ACCOUNT = 6176
PUSHER_INSTANCE_ID = '02ddcc80-b8db-42be-9022-44c546b4dce6'
PUSHER_KEY = environ.get("PUSHER_KEY", "").strip()

View File

@ -286,6 +286,7 @@ def api_comment(v):
body=body[:10000]
)
c.upvotes = 1
g.db.add(c)
g.db.flush()
@ -562,13 +563,14 @@ def api_comment(v):
)
g.db.add(vote)
cache.delete_memoized(comment_idlist)
v.comment_count = g.db.query(Comment.id).options(lazyload('*')).filter(Comment.author_id == v.id, Comment.parent_submission != None).filter_by(is_banned=False, deleted_utc=0).count()
g.db.add(v)
parent_post.comment_count = g.db.query(Comment.id).options(lazyload('*')).filter_by(parent_submission=parent_post.id).count()
parent_post.comment_count += 1
g.db.add(parent_post)
c.voted = 1

View File

@ -123,7 +123,8 @@ def post_id(pid, anything=None, v=None):
comments = comments.filter(Comment.author_id.notin_(shadowbanned))
comments=comments.filter(
Comment.parent_submission == post.id
Comment.parent_submission == post.id,
Comment.author_id != AUTOPOLLER_ACCOUNT,
).join(
votes,
votes.c.comment_id == Comment.id,
@ -161,7 +162,7 @@ def post_id(pid, anything=None, v=None):
else:
shadowbanned = [x[0] for x in g.db.query(User.id).options(lazyload('*')).filter(User.shadowbanned != None).all()]
comments = g.db.query(Comment).filter(Comment.parent_submission == post.id, Comment.author_id.notin_(shadowbanned))
comments = g.db.query(Comment).filter(Comment.parent_submission == post.id, Comment.author_id != AUTOPOLLER_ACCOUNT, Comment.author_id.notin_(shadowbanned))
if sort == "new":
comments = comments.order_by(Comment.created_utc.desc())
@ -730,9 +731,17 @@ def submit_post(v):
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999))', body, re.MULTILINE):
if "wikipedia" not in i.group(1): body = body.replace(i.group(1), f'![]({i.group(1)})')
body = re.sub('([^\n])\n([^\n])', r'\1\n\n\2', body)
options = []
for i in re.finditer('\s*\$([^\$]+)\$\s*', body):
options.append(i.group(1))
body = body.replace(i.group(0), "")
body_md = CustomRenderer().render(mistletoe.Document(body))
body_html = sanitize(body_md)
if len(body_html) > 20000: abort(400)
# Run safety filter
@ -806,6 +815,16 @@ def submit_post(v):
g.db.add(new_post)
g.db.flush()
for option in options:
c = Comment(author_id=AUTOPOLLER_ACCOUNT,
parent_submission=new_post.id,
level=1,
body=option,
)
g.db.add(c)
g.db.flush()
vote = Vote(user_id=v.id,
vote_type=1,
submission_id=new_post.id

View File

@ -160,4 +160,34 @@ def api_vote_comment(comment_id, new, v):
g.db.add(comment)
g.db.commit()
except: g.db.rollback()
return "", 204
@app.post("/vote/poll/<comment_id>")
@auth_required
def api_vote_poll(comment_id, v):
vote = request.values.get("vote")
if vote == "true": new = 1
elif vote == "false": new = 0
else: abort(400)
comment_id = int(comment_id)
comment = get_comment(comment_id)
existing = g.db.query(CommentVote).options(lazyload('*')).filter_by(user_id=v.id, comment_id=comment.id).first()
if existing and existing.vote_type == vote: return "", 204
if existing:
existing.vote_type = new
g.db.add(existing)
else:
vote = CommentVote(user_id=v.id, vote_type=new, comment_id=comment.id)
g.db.add(vote)
g.db.flush()
comment.upvotes = g.db.query(CommentVote.id).options(lazyload('*')).filter_by(comment_id=comment.id, vote_type=1).count()
g.db.add(comment)
g.db.commit()
return "", 204

View File

@ -33,14 +33,14 @@
{% if v %}
{% include "award_modal.html" %}
<script src="/assets/js/comments_v.js?v=8"></script>
<script src="/assets/js/comments_v.js?v=11"></script>
{% endif %}
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>
{% if v and v.admin_level == 6 %}
<script src="/assets/js/comments_admin.js?v=1"></script>
<script src="/assets/js/comments_admin.js?v=2"></script>
{% endif %}
<script>

View File

@ -1,33 +1,19 @@
<script>
function post(url, callback, errortext) {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
var form = new FormData()
form.append("formkey", formkey());
xhr.withCredentials=true;
xhr.onerror=function() { alert(errortext); };
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
callback();
} else {
xhr.onerror();
}
};
xhr.send(form);
};
function delete_postModal(id) {
function delete_post(){
this.innerHTML='<span class="spinner-border spinner-border-sm mr-2" role="status" aria-hidden="true"></span>Deleting post';
this.disabled = true;
post('/delete_post/' + id,
callback = function() {
location.reload();
}
)
var url = '/delete_post/' + id
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
var form = new FormData()
form.append("formkey", formkey());
xhr.withCredentials=true;
xhr.send(form);
location.reload();
}
document.getElementById("deletePostButton-mobile").onclick = delete_post;

View File

@ -1,4 +1,4 @@
<script src="/assets/js/gif_modal.js?v=5"></script>
<script src="/assets/js/gif_modal.js?v=6"></script>
<div class="modal fade" id="gifModal" tabindex="-1" role="dialog" aria-labelledby="gifModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered p-5" role="document">

View File

@ -6,7 +6,7 @@
{% include "emoji_modal.html" %}
{% include "gif_modal.html" %}
<script src="/assets/js/setting_profile.js?v=1"></script>
<script src="/assets/js/settings_profile.js?v=2"></script>
<div id="posts" class="row">

View File

@ -15,9 +15,25 @@
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>
<script src="/assets/js/new_comments_count.js?v=1"></script>
<script>
function poll_vote(cid) {
{% if v %}
var type = document.getElementById(cid).checked;
var scoretext = document.getElementById('poll-' + cid);
var score = Number(scoretext.textContent);
if (type == true) scoretext.textContent = score + 1;
else scoretext.textContent = score - 1;
post('/vote/poll/' + cid + '?vote=' + type);
{% else %}
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
document.getElementById('toast-post-error-text').innerText = "Only logged-in users can vote!";
{% endif %}
}
</script>
{% if v and v.id == p.author_id %}
<script>
<script>
togglePostEdit=function(id){
body=document.getElementById("post-body");
@ -34,9 +50,9 @@
{% endif %}
{% if 'marsey.tech' in request.host %}
{% if 'rdrama' not in request.host %}
{% if v %}
<script src="/assets/js/comments_v.js?v=8"></script>
<script src="/assets/js/comments_v.js?v=11"></script>
{% include "award_modal.html" %}
{% include "emoji_modal.html" %}
{% include "gif_modal.html" %}
@ -357,6 +373,15 @@
<pre></pre>
{% endif %}
{{p.realbody(v) | safe}}
{% for c in p.options %}
<div class="custom-control">
<input type="checkbox" class="custom-control-input" id="{{c.id}}" name="option" {% if c.poll_voted(v) %}checked{% endif %} onchange="poll_vote('{{c.id}}')">
<label class="custom-control-label" for="{{c.id}}">{{c.body}} - <a href="/votes?link=t3_{{c.id}}"><span id="poll-{{c.id}}">{{c.upvotes}}</span> votes</a></label>
</div>
{% endfor %}
</div>
{% if p.embed_url %}