forked from MarseyWorld/MarseyWorld
unpaywall profile views
parent
61612e7be3
commit
575a5080bd
|
@ -141,7 +141,6 @@ class User(Base):
|
||||||
subscriptions = relationship("Subscription", back_populates="user")
|
subscriptions = relationship("Subscription", back_populates="user")
|
||||||
following = relationship("Follow", primaryjoin="Follow.user_id==User.id", back_populates="user")
|
following = relationship("Follow", primaryjoin="Follow.user_id==User.id", back_populates="user")
|
||||||
followers = relationship("Follow", primaryjoin="Follow.target_id==User.id", back_populates="target")
|
followers = relationship("Follow", primaryjoin="Follow.target_id==User.id", back_populates="target")
|
||||||
viewers = relationship("ViewerRelationship", primaryjoin="User.id == ViewerRelationship.user_id")
|
|
||||||
blocking = relationship("UserBlock", lazy="dynamic", primaryjoin="User.id==UserBlock.user_id", back_populates="user")
|
blocking = relationship("UserBlock", lazy="dynamic", primaryjoin="User.id==UserBlock.user_id", back_populates="user")
|
||||||
blocked = relationship("UserBlock", lazy="dynamic", primaryjoin="User.id==UserBlock.target_id", back_populates="target")
|
blocked = relationship("UserBlock", lazy="dynamic", primaryjoin="User.id==UserBlock.target_id", back_populates="target")
|
||||||
authorizations = relationship("ClientAuth", back_populates="user")
|
authorizations = relationship("ClientAuth", back_populates="user")
|
||||||
|
@ -945,17 +944,6 @@ class User(Base):
|
||||||
def can_create_hole(self):
|
def can_create_hole(self):
|
||||||
return self.admin_level >= PERMS['HOLE_CREATE']
|
return self.admin_level >= PERMS['HOLE_CREATE']
|
||||||
|
|
||||||
@property
|
|
||||||
@lazy
|
|
||||||
def viewers_recorded(self):
|
|
||||||
if SITE_NAME == 'WPD': # WPD gets profile views
|
|
||||||
return True
|
|
||||||
elif self.admin_level >= PERMS['VIEW_PROFILE_VIEWS']: # Admins get profile views
|
|
||||||
return True
|
|
||||||
elif self.patron: # Patrons get profile views as a perk
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
def patron_tooltip(self):
|
def patron_tooltip(self):
|
||||||
|
|
|
@ -254,7 +254,6 @@ PERMS = { # Minimum admin_level to perform action.
|
||||||
'VIEW_CHUDRAMA': 1,
|
'VIEW_CHUDRAMA': 1,
|
||||||
'VIEW_PRIVATE_PROFILES': 2,
|
'VIEW_PRIVATE_PROFILES': 2,
|
||||||
'VIEW_ALTS': 2,
|
'VIEW_ALTS': 2,
|
||||||
'VIEW_PROFILE_VIEWS': 2,
|
|
||||||
'VIEW_ACTIVE_USERS': 2,
|
'VIEW_ACTIVE_USERS': 2,
|
||||||
'VIEW_ALL_USERS': 2,
|
'VIEW_ALL_USERS': 2,
|
||||||
'VIEW_ALT_VOTES': 2,
|
'VIEW_ALT_VOTES': 2,
|
||||||
|
|
|
@ -654,13 +654,20 @@ def following(username, v):
|
||||||
.order_by(Follow.created_utc).all()
|
.order_by(Follow.created_utc).all()
|
||||||
return render_template("userpage/following.html", v=v, u=u, users=users)
|
return render_template("userpage/following.html", v=v, u=u, users=users)
|
||||||
|
|
||||||
@app.get("/views")
|
@app.get("/@<username>/views")
|
||||||
@auth_required
|
@auth_required
|
||||||
def visitors(v:User):
|
def visitors(username, v:User):
|
||||||
if not v.viewers_recorded:
|
u = get_user(username, v=v, include_shadowbanned=False)
|
||||||
return render_template("errors/patron.html", v=v)
|
|
||||||
viewers=sorted(v.viewers, key = lambda x: x.last_view_utc, reverse=True)
|
try: page = int(request.values.get("page", 1))
|
||||||
return render_template("userpage/viewers.html", v=v, viewers=viewers)
|
except: page = 1
|
||||||
|
|
||||||
|
views = g.db.query(ViewerRelationship).filter_by(user_id=u.id).order_by(ViewerRelationship.last_view_utc.desc()).offset(PAGE_SIZE * (page - 1)).limit(PAGE_SIZE + 1).limit(PAGE_SIZE + 1).all()
|
||||||
|
|
||||||
|
next_exists = (len(views) > PAGE_SIZE)
|
||||||
|
views = views[:PAGE_SIZE]
|
||||||
|
|
||||||
|
return render_template("userpage/views.html", v=v, u=u, views=views, next_exists=next_exists, page=page)
|
||||||
|
|
||||||
@cache.memoize(timeout=86400)
|
@cache.memoize(timeout=86400)
|
||||||
def userpagelisting(user:User, site=None, v=None, page:int=1, sort="new", t="all"):
|
def userpagelisting(user:User, site=None, v=None, page:int=1, sort="new", t="all"):
|
||||||
|
@ -682,7 +689,7 @@ def u_username(username, v=None):
|
||||||
return redirect(SITE_FULL + request.full_path.replace(username, u.username))
|
return redirect(SITE_FULL + request.full_path.replace(username, u.username))
|
||||||
is_following = v and u.has_follower(v)
|
is_following = v and u.has_follower(v)
|
||||||
|
|
||||||
if v and v.id not in (u.id, DAD_ID) and u.viewers_recorded:
|
if v and v.id != u.id:
|
||||||
g.db.flush()
|
g.db.flush()
|
||||||
view = g.db.query(ViewerRelationship).filter_by(viewer_id=v.id, user_id=u.id).one_or_none()
|
view = g.db.query(ViewerRelationship).filter_by(viewer_id=v.id, user_id=u.id).one_or_none()
|
||||||
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
{% extends "default.html" %}
|
|
||||||
{% block pagetitle %}401 Not Authorized{% endblock %}
|
|
||||||
{% block pagetype %}error-401{% endblock %}
|
|
||||||
{% block content %}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-10 col-md-5">
|
|
||||||
<div class="text-center px-3 my-8">
|
|
||||||
<img alt=":#marseymerchant:" loading="lazy" class="mb-2" src="/e/marseymerchant.webp">
|
|
||||||
<h5>401 Not Authorized</h5>
|
|
||||||
<p class="text-muted">This page is only available to {% if SITE_NAME == 'rDrama' %}paypigs{% else %}patrons{% endif %}:</p>
|
|
||||||
{% if FEATURES['MARSEYBUX'] and v.truescore -%}
|
|
||||||
{% if KOFI_LINK %}
|
|
||||||
<a rel="nofollow noopener" href="{{KOFI_LINK}}">{{KOFI_LINK}}</a>
|
|
||||||
{% else %}
|
|
||||||
<a rel="nofollow noopener" href="{{GUMROAD_LINK}}">{{GUMROAD_LINK}}</a>
|
|
||||||
{% endif %}
|
|
||||||
{%- endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
|
@ -70,7 +70,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if v and (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']) -%}
|
{% if v and (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']) -%}
|
||||||
<div class="font-weight-bolder mb-2" id="profile--simphate"><a class="mr-1" href="/@{{u.username}}/upvoters">Simps</a> | <a class="mx-1" href="/@{{u.username}}/downvoters">Haters</a> | <a class="mx-1" href="/@{{u.username}}/upvoting">Simps For</a> | <a class="mx-1" href="/@{{u.username}}/downvoting">Hates</a> | <a class="ml-1" href="/@{{u.username}}/voted/posts">Voted</a></div>
|
<div class="font-weight-bolder mb-2" id="profile--simphate">
|
||||||
|
<a class="mr-1" href="/@{{u.username}}/views">Profile Views</a> | <a class="mx-1" href="/@{{u.username}}/upvoters">Simps</a> | <a class="mx-1" href="/@{{u.username}}/downvoters">Haters</a> | <a class="mx-1" href="/@{{u.username}}/upvoting">Simps For</a> | <a class="mx-1" href="/@{{u.username}}/downvoting">Hates</a> | <a class="ml-1" href="/@{{u.username}}/voted/posts">Voted</a>
|
||||||
|
</div>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="font-weight-bolder">
|
<div class="font-weight-bolder">
|
||||||
|
@ -188,7 +190,6 @@
|
||||||
<div class="actionbtns">
|
<div class="actionbtns">
|
||||||
{% if v and v.id == u.id %}
|
{% if v and v.id == u.id %}
|
||||||
<a href="/settings/personal" class="btn btn-secondary">Edit profile</a>
|
<a href="/settings/personal" class="btn btn-secondary">Edit profile</a>
|
||||||
<a href="/views" class="btn btn-secondary">Profile views</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if FEATURES['USERS_PROFILE_SONG'] and u.song and v and (v.id == u.id or v.mute and not u.unmutable) %}
|
{% if FEATURES['USERS_PROFILE_SONG'] and u.song and v and (v.id == u.id or v.mute and not u.unmutable) %}
|
||||||
|
@ -196,7 +197,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-2" id="profile--info">
|
<div class="mt-3" id="profile--info">
|
||||||
<p id="profile--info--id">User ID: {{u.id}}</p>
|
<p id="profile--info--id">User ID: {{u.id}}</p>
|
||||||
<p id="profile--info--spent">Coins spent: {{u.coins_spent}}</p>
|
<p id="profile--info--spent">Coins spent: {{u.coins_spent}}</p>
|
||||||
<p id="profile--info--truescore">True score: {{u.truescore}}</p>
|
<p id="profile--info--truescore">True score: {{u.truescore}}</p>
|
||||||
|
@ -302,7 +303,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if v and (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']) -%}
|
{% if v and (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']) -%}
|
||||||
<div class="font-weight-bolder mb-2" id="profile-mobile--simphate"><a class="mr-1" href="/@{{u.username}}/upvoters">Simps</a> | <a class="mx-1" href="/@{{u.username}}/downvoters">Haters</a> | <a class="mx-1" href="/@{{u.username}}/upvoting">Simps For</a> | <a class="mx-1" href="/@{{u.username}}/downvoting">Hates</a> | <a class="ml-1" href="/@{{u.username}}/voted/posts">Voted</a></div>
|
<div class="font-weight-bolder mb-2" id="profile-mobile--simphate">
|
||||||
|
<a class="mr-1" href="/@{{u.username}}/views">Profile Views</a> | <a class="mx-1" href="/@{{u.username}}/upvoters">Simps</a> | <a class="mx-1" href="/@{{u.username}}/downvoters">Haters</a> | <a class="mx-1" href="/@{{u.username}}/upvoting">Simps For</a> | <a class="mx-1" href="/@{{u.username}}/downvoting">Hates</a> | <a class="ml-1" href="/@{{u.username}}/voted/posts">Voted</a>
|
||||||
|
</div>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="font-weight-normal">
|
<div class="font-weight-normal">
|
||||||
|
@ -385,7 +388,6 @@
|
||||||
<div class="actionbtns">
|
<div class="actionbtns">
|
||||||
{% if v and v.id == u.id %}
|
{% if v and v.id == u.id %}
|
||||||
<a href="/settings/personal" class="btn btn-secondary ">Edit profile</a>
|
<a href="/settings/personal" class="btn btn-secondary ">Edit profile</a>
|
||||||
<a href="/views" class="btn btn-secondary">Profile views</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if FEATURES['USERS_PROFILE_SONG'] and u.song and v and (v.id == u.id or v.mute and not u.unmutable) %}
|
{% if FEATURES['USERS_PROFILE_SONG'] and u.song and v and (v.id == u.id or v.mute and not u.unmutable) %}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
{% extends "default.html" %}
|
|
||||||
{% block pagetitle %}Profile Viewers{% endblock %}
|
|
||||||
{% block content %}
|
|
||||||
<h5 class="pt-4 pl-2 my-1">Users who viewed your profile</h5>
|
|
||||||
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
|
||||||
<thead class="bg-primary text-white">
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Last visit</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
{% for view in viewers %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{% with user=view.viewer %}
|
|
||||||
{% include "user_in_table.html" %}
|
|
||||||
{% endwith %}
|
|
||||||
</td>
|
|
||||||
<td>{{view.last_view_string}}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
{% extends "default.html" %}
|
||||||
|
{% block pagetitle %}Profile Views{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h5 class="pt-4 pl-2 pb-3">Users who viewed @{{u.username}}'s profile</h5>
|
||||||
|
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
||||||
|
<thead class="bg-primary text-white">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Last visit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for view in views %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% with user=view.viewer %}
|
||||||
|
{% include "user_in_table.html" %}
|
||||||
|
{% endwith %}
|
||||||
|
</td>
|
||||||
|
<td>{{view.last_view_string}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block pagenav %}
|
||||||
|
<nav aria-label="Page navigation">
|
||||||
|
<ul class="pagination pagination-sm py-3 pl-3 mb-0">
|
||||||
|
{% if page>1 %}
|
||||||
|
<li class="page-item">
|
||||||
|
<small><a class="page-link" href="?page={{page-1}}" tabindex="-1">Prev</a></small>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled"><span class="page-link">Prev</span></li>
|
||||||
|
{% endif %}
|
||||||
|
{% if next_exists %}
|
||||||
|
<li class="page-item">
|
||||||
|
<small><a class="page-link" href="?page={{page+1}}">Next</a></small>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled"><span class="page-link">Next</span></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue