Add user profile page and projects list

This commit is contained in:
Drew DeVault 2020-04-28 09:53:14 -04:00
parent dfaf5bceb5
commit 55d590a4c4
4 changed files with 191 additions and 7 deletions

View File

@ -1,11 +1,48 @@
from flask import Blueprint
from flask import Blueprint, render_template
from hubsrht.types import User, Project, Visibility, Event, EventType
from srht.flask import paginate_query
from srht.oauth import current_user
users = Blueprint("users", __name__)
@users.route("/~<username>")
def summary_GET(username):
pass # TODO
user = User.query.filter(User.username == username).first()
if not user:
abort(404)
projects = (Project.query
.filter(Project.owner_id == current_user.id)
.order_by(Project.updated.desc()))
events = (Event.query
.filter(Event.user_id == current_user.id)
.order_by(Event.created.desc()))
if not current_user or current_user.id != user.id:
# TODO: ACLs
projects = projects.filter(Project.visibility == Visibility.public)
events = (events
.join(Project)
.filter(Project.visibility == Visibility.public))
projects = projects.limit(5).all()
events, pagination = paginate_query(events)
return render_template("profile.html",
user=user, projects=projects, EventType=EventType, events=events,
**pagination)
@users.route("/projects/<owner>")
def projects_GET(owner):
pass # TODO
if owner.startswith("~"):
owner = owner[1:]
owner = User.query.filter(User.username == owner).first()
if not owner:
abort(404)
projects = (Project.query
.filter(Project.owner_id == owner.id))
if not current_user or current_user.id != owner.id:
# TODO: ACLs
projects = projects.filter(Project.visibility == Visibility.public)
projects, pagination = paginate_query(projects)
return render_template("projects.html", user=owner, projects=projects,
**pagination)

View File

@ -7,7 +7,7 @@
<div class="row">
<div class="col-md-4">
<p>
Welcome back, {{current_user.canonical_name}}!
Welcome back, {{current_user.username}}!
This is the {{cfg("sr.ht", "site-name")}} hub service, which organizes
and indexes projects and users on the platform.
</p>
@ -59,7 +59,8 @@
</div>
<div class="pull-right">
<a
href="#"
href="{{url_for("users.projects_GET",
owner=current_user.canonical_name)}}"
class="btn btn-link"
>More projects&nbsp;{{icon("caret-right")}}</a>
</div>
@ -75,9 +76,9 @@
</div>
<div class="pull-right">
<a
href="#"
href="{{url_for("users.summary_GET", username=current_user.username)}}"
class="btn btn-link"
>More events&nbsp;{{icon("caret-right")}}</a>
>More on your profile&nbsp;{{icon("caret-right")}}</a>
</div>
</div>
</div>

View File

@ -0,0 +1,83 @@
{% extends "layout.html" %}
{% import "event.html" as eventutil with context %}
{% block title %}
<title>{{user.canonical_name}} on {{cfg("sr.ht", "site-name")}}</title>
{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-4">
<h2>
<a
href="{{url_for("users.summary_GET", username=user.username)}}"
>{{user.canonical_name}}</a>
</h2>
{% if user.location %}
<p>{{user.location}}</p>
{% endif %}
{% if user.url %}
<p>
<a
href="{{user.url}}"
target="_blank"
rel="me noopener noreferrer nofollow"
>{{user.url}}</a>
</p>
{% endif %}
{% if user.bio %}
<p>{{user.bio | md}}</p>
{% endif %}
</div>
<div class="col-md-8">
<div class="row">
<div class="col-md-12">
<hr class="d-md-none" />
<form action="{{url_for("users.projects_GET",
owner=user.canonical_name)}}"
>
<input
name="search"
type="text"
placeholder="Search {{user.canonical_name}}'s projects"
class="form-control" />
{% if search_error %}
<div class="invalid-feedback">{{ search_error }}</div>
{% endif %}
</form>
<div class="event-list">
{% for project in projects %}
<div class="event">
<h4>
{% if project.visibility.value != 'public' %}
<small class="text-muted pull-right">{{project.visibility.value}}</small>
{% endif %}
<a href="{{url_for("projects.summary_GET",
owner=project.owner.canonical_name,
project_name=project.name)}}">{{project.name}}</a>
</h4>
<p>{{project.description}}</p>
</div>
{% endfor %}
</div>
<div class="pull-right">
<a
href="{{url_for("users.projects_GET",
owner=current_user.canonical_name)}}"
class="btn btn-link"
>More projects&nbsp;{{icon("caret-right")}}</a>
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div class="col-md-12 event-list">
<h3>Activity</h3>
{% for event in events %}
{{ eventutil.event(event, project=True) }}
{% endfor %}
{{pagination()}}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,63 @@
{% extends "layout.html" %}
{% import "event.html" as eventutil with context %}
{% block title %}
<title>{{user.canonical_name}}'s projects - {{cfg("sr.ht", "site-name")}}</title>
{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-4">
<h2>
<a
href="{{url_for("users.summary_GET", username=user.username)}}"
>{{user.canonical_name}}</a>
</h2>
{% if user.location %}
<p>{{user.location}}</p>
{% endif %}
{% if user.url %}
<p>
<a
href="{{user.url}}"
target="_blank"
rel="me noopener noreferrer nofollow"
>{{user.url}}</a>
</p>
{% endif %}
{% if user.bio %}
<p>{{user.bio | md}}</p>
{% endif %}
</div>
<div class="col-md-8">
<form action="{{url_for("users.projects_GET",
owner=user.canonical_name)}}"
>
<input
name="search"
type="text"
placeholder="Search your projects"
class="form-control"
value="{{search if search else ""}}" />
{% if search_error %}
<div class="invalid-feedback">{{ search_error }}</div>
{% endif %}
</form>
<div class="event-list">
{% for project in projects %}
<div class="event">
<h4>
{% if project.visibility.value != 'public' %}
<small class="text-muted pull-right">{{project.visibility.value}}</small>
{% endif %}
<a href="{{url_for("projects.summary_GET",
owner=project.owner.canonical_name,
project_name=project.name)}}">{{project.name}}</a>
</h4>
<p>{{project.description}}</p>
</div>
{% endfor %}
</div>
{{pagination()}}
</div>
</div>
{% endblock %}