Merge pull request #4 from Aevann1/experimental

sex
remotes/1693045480750635534/spooky-22
fireworks88 2021-07-28 00:20:05 +00:00 committed by GitHub
commit 3f40c30d3b
14 changed files with 517 additions and 40 deletions

1
.gitignore vendored
View File

@ -112,3 +112,4 @@ package-lock.json
local.txt
*.scssc
.idea/*
disablesignups

View File

@ -3,18 +3,20 @@
from sqlalchemy import *
from sqlalchemy.orm import relationship
#from .mix_ins import *
from drama.__main__ import Base
from drama.__main__ import Base, app
AWARDS = {
"ban": {
"kind": "ban",
"title": "1-Day Ban",
"description": "Ban the author for a day.",
"icon": "fas fa-gavel",
"color": "text-danger"
},
"shit": {
"kind": "shit",
"title": "Literal Shitpost",
"description": "Let OP know how much their post sucks ass.",
"description": "Let OP know how much their post sucks ass. Flies will swarm their idiotic post. (flies only work on posts lol!!)",
"icon": "fas fa-poop",
"color": "text-black-50"
}
@ -28,8 +30,8 @@ class AwardRelationship(Base):
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("users.id"))
submission_id = Column(Integer, ForeignKey("submissions.id"))
comment_id = Column(Integer, ForeignKey("comments.id"))
submission_id = Column(Integer, ForeignKey("submissions.id"), default=None)
comment_id = Column(Integer, ForeignKey("comments.id"), default=None)
kind = Column(String(20))
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", lazy="joined")
@ -44,6 +46,18 @@ class AwardRelationship(Base):
lazy="joined"
)
@property
def given(self):
return bool(self.submission_id) or bool(self.comment_id)
@property
def type(self):
return AWARDS[self.kind]
@property
def title(self):
return self.type['title']
@property
def class_list(self):
return self.type['icon']+' '+self.type['color']

View File

@ -67,7 +67,7 @@ class Comment(Base, Age_times, Scores, Stndrd, Fuzzing):
parent_comment = relationship("Comment", remote_side=[id])
child_comments = relationship("Comment", remote_side=[parent_comment_id])
#awards = relationship("AwardRelationship", lazy="joined")
awards = relationship("AwardRelationship", lazy="joined")
# These are virtual properties handled as postgres functions server-side
# There is no difference to SQLAlchemy, but they cannot be written to

View File

@ -90,7 +90,7 @@ class Submission(Base, Stndrd, Age_times, Scores, Fuzzing):
comment_count = Column(Integer, server_default=FetchedValue())
score = deferred(Column(Float, server_default=FetchedValue()))
#awards = relationship("AwardRelationship", lazy="joined")
awards = relationship("AwardRelationship", lazy="joined")
def __init__(self, *args, **kwargs):
@ -284,6 +284,9 @@ class Submission(Base, Stndrd, Age_times, Scores, Fuzzing):
return data
def has_award(self, kind):
return bool(len([x for x in self.awards if x.kind == kind]))
@property
def voted(self):
return self._voted if "_voted" in self.__dict__ else 0

View File

@ -104,6 +104,12 @@ class User(Base, Stndrd, Age_times):
lazy="dynamic",
primaryjoin="User.id==SaveRelationship.user_id")
awards = relationship(
"AwardRelationship",
lazy="dynamic",
primaryjoin="User.id==AwardRelationship.user_id"
)
# properties defined as SQL server-side functions
referral_count = deferred(Column(Integer, server_default=FetchedValue()))

View File

@ -12,4 +12,5 @@ from .settings import *
from .static import *
from .users import *
from .votes import *
from .feeds import *
from .feeds import *
from .awards import *

View File

@ -0,0 +1,211 @@
from drama.__main__ import app
from drama.helpers.wrappers import *
from drama.helpers.alerts import *
from drama.helpers.get import *
from drama.classes.award import *
from flask import g, jsonify, request
def banaward_trigger(post=None, comment=None):
author = post.author if post else comment.author
link = f"[this post]({post.permalink})" if post else f"[this comment]({comment.permalink})"
if author.admin_level < 1:
if not author.is_suspended:
author.ban(reason="1-day ban award used", days=1)
send_notification(1046, author, f"Your Drama account has been suspended for a day for {link}. It sucked and you should feel bad.")
elif author.unban_utc > 0:
author.unban_utc += 24*60*60
g.db.add(author)
send_notification(1046, author,
f"Your Drama account has been suspended for yet another day for {link}. Seriously man?")
ACTIONS = {
"ban": banaward_trigger
}
ALLOW_MULTIPLE = (
"ban",
)
@app.get("/api/awards")
@auth_required
def get_awards(v):
return_value = list(AWARDS.values())
user_awards = v.awards
for val in return_value:
val['owned'] = len([x for x in user_awards if x.kind == val['kind'] and not x.given])
return jsonify(return_value)
@app.put("/api/post/<pid>/awards")
@auth_required
@validate_formkey
def award_post(pid, v):
if v.is_suspended and v.unban_utc == 0:
return jsonify({"error": "forbidden"}), 403
kind = request.form.get("kind", "")
if kind not in AWARDS:
return jsonify({"error": "That award doesn't exist."}), 404
post_award = g.db.query(AwardRelationship).filter(
and_(
AwardRelationship.kind == kind,
AwardRelationship.user_id == v.id,
AwardRelationship.submission_id == None,
AwardRelationship.comment_id == None
)
).first()
if not post_award:
return jsonify({"error": "You don't have that award."}), 404
post = g.db.query(Submission).filter_by(id=pid).first()
if not post or post.is_banned or post.deleted_utc > 0:
return jsonify({"error": "That post doesn't exist or has been deleted or removed."}), 404
if post.author_id == v.id:
return jsonify({"error": "You can't award yourself."}), 403
existing_award = g.db.query(AwardRelationship).filter(
and_(
AwardRelationship.submission_id == post.id,
AwardRelationship.user_id == v.id,
AwardRelationship.kind == kind
)
).first()
if existing_award and kind not in ALLOW_MULTIPLE:
return jsonify({"error": "You can't give that award multiple times to the same post."}), 409
post_award.submission_id = post.id
#print(f"give award to pid {post_award.submission_id} ({post.id})")
g.db.add(post_award)
msg = f"@{v.username} has given your [post]({post.permalink}) the {AWARDS[kind]['title']} Award!"
note = request.form.get("note", "")
if note:
msg += f"\n\n> {note}"
send_notification(1046, post.author, msg)
if kind in ACTIONS:
ACTIONS[kind](post=post)
return "", 204
@app.put("/api/comment/<cid>/awards")
@auth_required
@validate_formkey
def award_comment(cid, v):
if v.is_suspended and v.unban_utc == 0:
return jsonify({"error": "forbidden"}), 403
kind = request.form.get("kind", "")
if kind not in AWARDS:
return jsonify({"error": "That award doesn't exist."}), 404
comment_award = g.db.query(AwardRelationship).filter(
and_(
AwardRelationship.kind == kind,
AwardRelationship.user_id == v.id,
AwardRelationship.submission_id == None,
AwardRelationship.comment_id == None
)
).first()
if not comment_award:
return jsonify({"error": "You don't have that award."}), 404
c = g.db.query(Comment).filter_by(id=cid).first()
if not c or c.is_banned or c.deleted_utc > 0:
return jsonify({"error": "That comment doesn't exist or has been deleted or removed."}), 404
if c.author_id == v.id:
return jsonify({"error": "You can't award yourself."}), 403
existing_award = g.db.query(AwardRelationship).filter(
and_(
AwardRelationship.comment_id == c.id,
AwardRelationship.user_id == v.id,
AwardRelationship.kind == kind
)
).first()
if existing_award and kind not in ALLOW_MULTIPLE:
return jsonify({"error": "You can't give that award multiple times to the same comment."}), 409
comment_award.comment_id = c.id
g.db.add(comment_award)
msg = f"@{v.username} has given your [comment]({c.permalink}) the {AWARDS[kind]['title']} Award!"
note = request.form.get("note", "")
if note:
msg += f"\n\n> {note}"
send_notification(1046, c.author, msg)
if kind in ACTIONS:
ACTIONS[kind](comment=c)
return "", 204
@app.get("/admin/user_award")
@auth_required
def admin_userawards_get(v):
if v.admin_level < 6:
abort(403)
return render_template("admin/user_award.html", awards=list(AWARDS.values()), v=v)
@app.post("/admin/user_award")
@auth_required
@validate_formkey
def admin_userawards_post(v):
if v.admin_level < 6:
abort(403)
u = get_user(request.form.get("username", '1'), graceful=False, v=v)
awards = []
latest = g.db.query(AwardRelationship).order_by(AwardRelationship.id.desc()).first()
thing = latest.id
for key, value in request.form.items():
if key not in AWARDS:
continue
if value:
for x in range(int(value)):
thing += 1
awards.append(AwardRelationship(
id=thing,
user_id=u.id,
kind=key
))
g.db.bulk_save_objects(awards)
return redirect(f'/@{u.username}')

View File

@ -10,6 +10,7 @@
<pre></pre>
<h4>&nbsp;Admin Tools</h4>
{% filter markdown %}
* [Grant User Award](/admin/user_award)
* [Advanced Stats](/api/user_stat_data)
* [Ban Domain](/admin/domain/enter%20domain%20here)
* [Shadowbanned Users](/admin/shadowbanned)

View File

@ -0,0 +1,66 @@
{% extends "default.html" %}
{% block title %}
<title>Grant User Award</title>
{% endblock %}
{% block pagetype %}message{% endblock %}
{% block content %}
{% if error %}
<div class="alert alert-danger alert-dismissible fade show my-3" role="alert">
<i class="fas fa-exclamation-circle my-auto"></i>
<span>
{{error}}
</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true"><i class="far fa-times"></i></span>
</button>
</div>
{% endif %}
{% if msg %}
<div class="alert alert-success alert-dismissible fade show my-3" role="alert">
<i class="fas fa-check-circle my-auto" aria-hidden="true"></i>
<span>
{{msg}}
</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true"><i class="far fa-times"></i></span>
</button>
</div>
{% endif %}
<pre></pre>
<pre></pre>
<h5>User Award Grant</h5>
<form action="/admin/user_award", method="post">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<label for="input-username">Username</label><br>
<input id="input-username" class="form-control mb-3" type="text" name="username" required>
<table class="table table-striped">
<thead class="bg-primary text-white">
<tr>
<th scope="col">Icon</th>
<th scope="col">Title</th>
<th scope="col">Amount</th>
</tr>
</thead>
<tbody>
{% for a in awards %}
<tr>
<td><i class="{{ a['icon'] }} {{ a['color'] }}" style="font-size: 30px"></i></td>
<td style="font-weight: bold">{{ a['title'] }}</td>
<td><input type="number" class="form-control" name="{{ a['kind'] }}" value="0" placeholder="enter amount" /></td>
</tr>
{% endfor %}
</table>
<input class="btn btn-primary mt-3" type="submit" value="Grant Awards">
</form>
{% endblock %}

View File

@ -0,0 +1,152 @@
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<input type="hidden" id="awardTarget" value="" />
<div class="modal fade" id="awardModal" tabindex="-1" role="dialog" aria-labelledby="awardModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Give Award</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="far fa-times"></i></span>
</button>
</div>
<div id="awardModalBody" class="modal-body">
<form v-if="loaded" id="sex" class="pt-3 pb-0">
<div class="card-columns awards-wrapper">
<div v-for="(award, index) in awards" :key="index">
<input type="radio" :id="index" :value="index" v-model="picked" :disabled="award.owned < 1">
<label class="card" :for="index" :class="{ disabled: award.owned < 1 }">
<i :class="award.icon+' '+award.color"></i><br />
<span class="d-block pt-2" style="font-weight: bold; font-size: 14px;">[[ award.title ]]</span>
<span class="text-muted">[[ award.owned ]] owned</span>
</label>
</div>
</div>
<div v-if="picked !== null">
<div class="award-desc p-3">
<i style="font-size: 35px;" :class="pickedAward.icon+' '+pickedAward.color"></i>
<div style="margin-left: 15px;">
<strong>[[ pickedAward.title ]] Award</strong><br />
<span class="text-muted">[[ pickedAward.description ]]</span>
</div>
</div>
<label for="note" class="pt-4">Note (optional):</label>
<textarea id="note" name="note" v-model="note" class="form-control" placeholder="Note to include in award notification"></textarea>
</div>
</form>
<div v-else-if="error" class="p-5 text-center">
<h4>Failed to fetch awards</h4>
<button class="btn btn-primary">Retry</button>
</div>
<div v-else class="p-5 text-center">
<h4>Loading...</h4>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link text-muted" data-dismiss="modal">Cancel</button>
<button v-if="pending" class="btn btn-warning" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Gifting...
</button>
<button v-else type="submit" class="btn btn-warning" id="awardButton" @click="submit" :disabled="pickedAward === null">Give Award</button>
</div>
</div>
</div>
</div>
<style>
.awards-wrapper input[type="radio"] {
display: none;
}
.awards-wrapper label {
cursor: pointer;
padding: 15px;
text-align: center;
text-transform: none!important;
}
.awards-wrapper label i {
font-size: 45px;
}
.awards-wrapper label.disabled {
opacity: 0.6;
}
.awards-wrapper label:hover {
/*background-color: rgba(173, 226, 255, 0.7)!important;*/
background-color: var(--primary)!important;
background-opacity: 0.4;
}
.awards-wrapper input[type="radio"]:checked+label {
/*background-color: rgba(173, 226, 255, 0.9)!important;*/
background-color: var(--primary)!important;
background-opacity: 0.9;
}
.award-desc {
border-radius: 5px;
background-color: rgba(221, 221, 221, 0.23);
display: flex;
}
</style>
<script>
new Vue({
el: "#awardModal",
delimiters: ['[[', ']]'],
data: {
loaded: false,
error: false,
pending: false,
awards: [],
picked: null,
note: ""
},
computed: {
pickedAward: function() {
if (this.picked !== null) {
return this.awards[this.picked];
} else {
return null;
}
}
},
methods: {
async submit() {
this.pending = true;
const target = document.getElementById("awardTarget").value;
const f = new FormData();
f.append("formkey", formkey());
f.append("kind", this.pickedAward.kind || "");
f.append("note", this.note)
let response = await fetch(target, {
method: "PUT",
body: f
});
if (response.ok) {
location.reload();
} else {
this.pending = false;
let s = await response.json();
alert(s.error);
}
}
},
mounted() {
fetch('/api/awards')
.then(response => response.json())
.then(json => {
this.awards = json;
});
this.loaded = true;
}
})
</script>

View File

@ -130,7 +130,13 @@
{% if c.edited_utc %}
<span class="time-edited"><span>&#183;</span> <span class="font-italic">Edited {{c.edited_string}}</span></span>
{% endif %}
{% if c.awards %}
{% for a in c.awards[:5] %}
<i class="{{ a.class_list }} px-1" data-toggle="tooltip" data-placement="bottom" title="{{ a.title }} Award given by @{{a.user.username}}"></i>
{% endfor %}
{% endif %}
</div>
{% if c.is_banned and c.ban_reason %}
@ -241,14 +247,6 @@
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="/votes?link=https://rdrama.net{{c.permalink}}"><i class="fas fa-arrows-v"></i>Votes</a></li>
{% if v and v.id!=c.author_id and v.admin_level == 0 %}
{% if v.banawards > 0 %}
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" onclick="post_toast('/banaward/comment/{{c.id}}')"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
{% else %}
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="/banaward/comment/{{c.id}}"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
{% endif %}
{% endif %}
{% if v and c.id in v.saved_comment_idlist() %}
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" onclick="post('/unsave_comment/{{c.base36id}}', function(){window.location.reload(true);})"><i class="fas fa-save"></i>Unsave</a></li>
{% else %}
@ -259,6 +257,11 @@
<li class="list-inline-item text-muted"><a href="javascript:void(0)" onclick="document.getElementById('reply-to-{{c.base36id}}').classList.remove('d-none')"><i class="fas fa-reply"
aria-hidden="true"></i><span class="d-none d-md-inline-block">Reply</span></a></li>
{% if v.id!=c.author_id %}
<li class="list-inline-item text-muted"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/comment/{{c.id}}/awards')"><i class="fas fa-gift"
aria-hidden="true"></i><span class="d-none d-md-inline-block">Give Award</span></a></li>
{% endif %}
{% endif %}
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="{{c.permalink}}?context=99#context"{% if c.author.is_private %} rel="nofollow"{% endif %}><i class="fas fa-book-open"></i>Context</a></li>
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0);" role="button" class="copy-link" data-clipboard-text="{{c.permalink | full_link}}?context=99#context"><i class="fas fa-copy"></i>Copy link</a></li>

View File

@ -408,6 +408,14 @@
}
}
// award modal
function awardModal(link) {
var target = document.getElementById("awardTarget");
target.value = link;
}
// Expand Images on Desktop
function expandDesktopImage(image, link) {
@ -1072,6 +1080,7 @@
</div>
{% if v %}
{% include "award_modal.html" %}
{% include "flag_post_modal.html" %}
{% include "flag_comment_modal.html" %}
{% include "gif_modal.html" %}

View File

@ -116,12 +116,8 @@
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v text-center text-muted mr-3"></i>Votes</a></button>
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
{% if v.banawards > 0 %}
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
{% else %}
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
{% endif %}
{% if v and v.id!=p.author_id %}
<button class="btn btn-link btn-block btn-lg text-left text-muted" data-toggle="modal" data-dismiss="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift text-center text-muted mr-3"></i>Give Award</button>
{% endif %}
{% if v and p.id in v.subscribed_idlist() %}
@ -189,6 +185,20 @@
{% endblock %}
{% block content %}
{% if p.has_award("shit") %}
<script src="/assets/js/bug-min.js" type="text/javascript"></script>
<script type="text/javascript">
new BugController({
imageSprite: "/assets/js/fly-sprite.png",
canDie: false,
minBugs: 80,
maxBugs: 100,
mouseOver: "multiply"
});
</script>
{% endif %}
<div class="row mb-3">
<div class="col-12">
@ -224,6 +234,12 @@
{% if p.edited_utc %}&nbsp;&nbsp;Edited <span data-toggle="tooltip" data-placement="bottom" id="edited_timestamp" title="">{{p.edited_string}}</span>{% endif %}
&nbsp;&nbsp;{{p.views}} views
{% if p.awards %}
{% for a in p.awards[:5] %}
<i class="{{ a.class_list }} px-1" data-toggle="tooltip" data-placement="bottom" title="{{ a.title }} Award given by @{{a.user.username}}"></i>
{% endfor %}
{% endif %}
</div>
{% if p.realurl(v) %}
@ -308,12 +324,8 @@
<li class="list-inline-item"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v"></i>Votes</a></li>
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
{% if v.banawards > 0 %}
<li class="list-inline-item"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
{% else %}
<li class="list-inline-item"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
{% endif %}
{% if v and v.id!=p.author_id %}
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift fa-fw"></i>Give Award</a></li>
{% endif %}
<li class="list-inline-item"><a href="javascript:void(0);" role="button" class="copy-link" data-clipboard-text="{{p.permalink | full_link}}"><i class="fas fa-copy"></i>Copy link</a></li>

View File

@ -145,6 +145,12 @@
{% if p.edited_utc %}&nbsp;&nbsp;Edited <span data-toggle="tooltip" data-placement="bottom" id="edited_timestamp-{{p.id}}" title="">{{p.edited_string}}</span>{% endif %}
&nbsp;&nbsp;{{p.views}} views
{% if p.awards %}
{% for a in p.awards[:5] %}
<i class="{{ a.class_list }} px-1" data-toggle="tooltip" data-placement="bottom" title="{{ a.title }} Award given by @{{a.user.username}}"></i>
{% endfor %}
{% endif %}
</div>
<h5 class="card-title post-title text-left w-lg-75 mb-0 pb-0 pb-md-1"><a {% if v and v.newtab %}target="_blank"{% endif %} href="{{p.permalink}}" class="stretched-link" {% if p.author.is_private %} rel="nofollow"{% endif %}>
@ -168,12 +174,8 @@
<li class="list-inline-item"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v"></i>Votes</a></li>
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
{% if v.banawards > 0 %}
<li class="list-inline-item"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
{% else %}
<li class="list-inline-item"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
{% endif %}
{% if v and v.id!=p.author_id %}
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift fa-fw"></i>Give Award</a></li>
{% endif %}
<li class="list-inline-item"><a href="javascript:void(0);" role="button" class="copy-link" data-clipboard-text="{{p.permalink | full_link}}"><i class="fas fa-copy"></i>Copy link</a></li>
@ -353,12 +355,8 @@
<ul class="list-group post-actions">
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v text-center text-muted mr-3"></i>Votes</a></button>
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
{% if v.banawards > 0 %}
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
{% else %}
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
{% endif %}
{% if v and v.id!=p.author_id %}
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift fa-fw"></i>Give Award</a></li>
{% endif %}
{% if v and p.id in v.subscribed_idlist() %}