mirror of https://git.sr.ht/~sircmpwn/hub.sr.ht
add project RSS feed
Signed-off-by: Vlad-Stefan Harbuz <vlad@vladh.net>
This commit is contained in:
parent
fce16cc33e
commit
fb56d7ba60
|
@ -0,0 +1,32 @@
|
|||
"""Expand external events
|
||||
|
||||
Revision ID: 9cfb231405a9
|
||||
Revises: e748f55a827c
|
||||
Create Date: 2022-11-14 18:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '9cfb231405a9'
|
||||
down_revision = 'e748f55a827c'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.execute("""
|
||||
ALTER TABLE "event"
|
||||
ADD COLUMN external_summary_plain character varying,
|
||||
ADD COLUMN external_details_plain character varying,
|
||||
ADD COLUMN external_url character varying;
|
||||
""")
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.execute("""
|
||||
ALTER TABLE "event"
|
||||
DROP COLUMN external_summary_plain,
|
||||
DROP COLUMN external_details_plain,
|
||||
DROP COLUMN external_url;
|
||||
""")
|
|
@ -1,7 +1,8 @@
|
|||
import re
|
||||
import string
|
||||
from sqlalchemy import or_
|
||||
from flask import Blueprint, Response, render_template, request, redirect, url_for, abort
|
||||
from flask import Blueprint, Response, render_template, request, redirect, url_for, \
|
||||
abort, make_response
|
||||
from flask import session
|
||||
from hubsrht.decorators import adminrequired
|
||||
from hubsrht.projects import ProjectAccess, get_project
|
||||
|
@ -135,6 +136,31 @@ def feed_GET(owner, project_name):
|
|||
view="summary", owner=owner, project=project,
|
||||
events=events, EventType=EventType, **pagination)
|
||||
|
||||
@projects.route("/<owner>/<project_name>/feed.rss")
|
||||
def feed_rss_GET(owner, project_name):
|
||||
owner, project = get_project(owner, project_name, ProjectAccess.read)
|
||||
|
||||
events = (Event.query
|
||||
.filter(Event.project_id == project.id)
|
||||
.order_by(Event.created.desc()))
|
||||
|
||||
if not current_user or current_user.id != owner.id:
|
||||
events = (events
|
||||
.outerjoin(SourceRepo)
|
||||
.outerjoin(MailingList)
|
||||
.outerjoin(Tracker)
|
||||
.filter(or_(Event.source_repo == None, SourceRepo.visibility == Visibility.PUBLIC),
|
||||
or_(Event.mailing_list == None, MailingList.visibility == Visibility.PUBLIC),
|
||||
or_(Event.tracker == None, Tracker.visibility == Visibility.PUBLIC)))
|
||||
|
||||
events, pagination = paginate_query(events)
|
||||
|
||||
res = make_response(render_template("project-feed-rss.html",
|
||||
view="summary", owner=owner, project=project,
|
||||
events=events, EventType=EventType, **pagination))
|
||||
res.headers['Content-Type'] = 'text/xml; charset=utf-8'
|
||||
return res
|
||||
|
||||
@projects.route("/<owner>/<project_name>/dismiss-checklist", methods=["POST"])
|
||||
@loginrequired
|
||||
def dismiss_checklist_POST(owner, project_name):
|
||||
|
|
|
@ -95,9 +95,12 @@ def git_repo(repo_id):
|
|||
event.external_summary = (
|
||||
f"<a href='{commit_url}'>{commit_sha}</a> " +
|
||||
f"<code>{html.escape(commit_message)}</code>")
|
||||
event.external_summary_plain = f"{commit_sha} - {commit_message}"
|
||||
event.external_details = (
|
||||
f"<a href='{pusher_url}'>{pusher_name}</a> pushed to " +
|
||||
f"<a href='{repo.url()}'>{repo_name}</a> git")
|
||||
event.external_details_plain = f"{pusher_name} pushed to {repo_name} git"
|
||||
event.external_url = commit_url
|
||||
|
||||
repo.project.updated = datetime.utcnow()
|
||||
db.session.add(event)
|
||||
|
@ -243,15 +246,18 @@ def mailing_list(list_id):
|
|||
elif event == "post:received":
|
||||
event = Event()
|
||||
sender = payload["sender"]
|
||||
sender_name = "Unknown"
|
||||
if sender:
|
||||
sender = current_app.oauth_service.lookup_user(sender['name'])
|
||||
event.user_id = sender.id
|
||||
sender_name = sender.canonical_name
|
||||
sender_url = f"<a href='{_listssrht}/{sender.canonical_name}'>{sender.canonical_name}</a>"
|
||||
else:
|
||||
msg = email.message_from_string(payload["envelope"],
|
||||
policy=email.policy.SMTP)
|
||||
sender = email.utils.parseaddr(msg['From'])
|
||||
sender_url = sender[0] if sender[0] else sender[1]
|
||||
sender_name = sender[0] if sender[0] else sender[1]
|
||||
sender_url = sender_name
|
||||
|
||||
event.event_type = EventType.external_event
|
||||
event.mailing_list_id = ml.id
|
||||
|
@ -263,8 +269,11 @@ def mailing_list(list_id):
|
|||
event.external_source = "todo.sr.ht"
|
||||
event.external_summary = (
|
||||
f"<a href='{archive_url}'>{html.escape(subject)}</a>")
|
||||
event.external_summary_plain = subject
|
||||
event.external_details = (
|
||||
f"{sender_url} via <a href='{ml.url()}'>{ml.name}</a>")
|
||||
event.external_details_plain = f"{sender_name} via {ml.name}"
|
||||
event.external_url = archive_url
|
||||
|
||||
db.session.add(event)
|
||||
db.session.commit()
|
||||
|
@ -354,9 +363,12 @@ def todo_tracker(tracker_id):
|
|||
event.external_summary = (
|
||||
f"<a href='{ticket_url}'>#{ticket_id}</a> " +
|
||||
f"{html.escape(ticket_subject)}")
|
||||
event.external_summary_plain = f"#{ticket_id} {ticket_subject}"
|
||||
event.external_details = (
|
||||
f"{submitter_url} filed ticket on " +
|
||||
f"<a href='{tracker.url()}'>{tracker.name}</a> todo")
|
||||
event.external_details_plain = f"{submitter['canonical_name']} filed ticket on {tracker.name} todo"
|
||||
event.external_url = ticket_url
|
||||
|
||||
db.session.add(event)
|
||||
db.session.commit()
|
||||
|
@ -404,9 +416,12 @@ def todo_ticket(tracker_id):
|
|||
event.external_summary = (
|
||||
f"<a href='{ticket_url}'>#{ticket_id}</a> " +
|
||||
f"{html.escape(ticket_subject)}")
|
||||
event.external_summary_plain = f"#{ticket_id} {ticket_subject}"
|
||||
event.external_details = (
|
||||
f"{participant_url} commented on " +
|
||||
f"<a href='{tracker.url()}'>{tracker.name}</a> todo")
|
||||
event.external_details_plain = f"{participant['canonical_name']} commented on {tracker.name} todo"
|
||||
event.external_url = ticket_url
|
||||
|
||||
db.session.add(event)
|
||||
db.session.commit()
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
{% macro event(event, project=False) %}
|
||||
<item>
|
||||
<pubDate>{{event.created}}</pubDate>
|
||||
<guid>{{project.owner.canonical_name}}/{{project.name}}#{{event.id}}</guid>
|
||||
{% if event.event_type == EventType.source_repo_added %}
|
||||
<link>{{event.source_repo.url()}}</link>
|
||||
<title>{{event.source_repo.owner.canonical_name}}/{{event.source_repo.name}}</title>
|
||||
<description>New {{event.source_repo.repo_type.value}} repository added</description>
|
||||
{% elif event.event_type == EventType.mailing_list_added %}
|
||||
<link>{{event.mailing_list.url()}}</link>
|
||||
<title>{{event.mailing_list.owner.canonical_name}}/{{event.mailing_list.name}}</title>
|
||||
<description>New mailing list added</description>
|
||||
{% elif event.event_type == EventType.tracker_added %}
|
||||
<link>{{event.tracker.url()}}</link>
|
||||
<title>{{event.tracker.owner.canonical_name}}/{{event.tracker.name}}</title>
|
||||
<description>New ticket tracker added</description>
|
||||
{% elif event.event_type == EventType.external_event %}
|
||||
<link>{{event.external_url or ""}}</link>
|
||||
<title>{{event.external_summary_plain or ""}}</title>
|
||||
<description>{{event.external_details_plain or ""}}</description>
|
||||
{% else %}
|
||||
{% endif %}
|
||||
</item>
|
||||
{% endmacro %}
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
{% import "event-rss.html" as event_rss_tpl with context %}
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{project.name}} activity</title>
|
||||
<link>{{url_for("projects.summary_GET",
|
||||
owner=project.owner.canonical_name,
|
||||
project_name=project.name)}}</link>
|
||||
<description>{{project.owner.canonical_name}}/{{project.name}}</description>
|
||||
<atom:link href="{{url_for('projects.feed_rss_GET',
|
||||
owner=project.owner.canonical_name,
|
||||
project_name=project.name)}}" rel="self" type="application/rss+xml" />
|
||||
{% for event in events %}
|
||||
{{ event_rss_tpl.event(event, project) }}
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
|
@ -3,7 +3,6 @@
|
|||
{% block title %}
|
||||
<title>{{project.name}} activity</title>
|
||||
{% endblock %}
|
||||
{# TODO: RSS feed #}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
|
|
@ -125,6 +125,11 @@
|
|||
owner=owner, project_name=project.name)}}"
|
||||
class="btn btn-link"
|
||||
>View project feed {{icon("caret-right")}}</a>
|
||||
<a
|
||||
href="{{url_for("projects.feed_rss_GET",
|
||||
owner=owner, project_name=project.name)}}"
|
||||
class="btn btn-link"
|
||||
>RSS {{icon("caret-right")}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -48,3 +48,6 @@ class Event(Base):
|
|||
external_source = sa.Column(sa.Unicode) # e.g. "lists.sr.ht"
|
||||
external_summary = sa.Column(sa.Unicode) # markdown
|
||||
external_details = sa.Column(sa.Unicode) # markdown
|
||||
external_summary_plain = sa.Column(sa.Unicode) # plaintext
|
||||
external_details_plain = sa.Column(sa.Unicode) # plaintext
|
||||
external_url = sa.Column(sa.Unicode)
|
||||
|
|
|
@ -96,5 +96,8 @@ CREATE TABLE event (
|
|||
tracker_id integer REFERENCES tracker(id) ON DELETE CASCADE,
|
||||
external_source character varying,
|
||||
external_summary character varying,
|
||||
external_details character varying
|
||||
external_details character varying,
|
||||
external_summary_plain character varying,
|
||||
external_details_plain character varying,
|
||||
external_url character varying
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue