mirror of
https://github.com/YunoHost/tartiflette.git
synced 2024-09-03 20:06:08 +02:00
RSS feed implementation
This commit is contained in:
parent
c33bf8596f
commit
1431c3b0ba
6 changed files with 95 additions and 91 deletions
15
app/app.py
15
app/app.py
|
@ -174,13 +174,26 @@ def appsobservatory_history():
|
|||
data = json.loads(open("./app/scripts/appListsHistory/count_history.json").read())
|
||||
return render_template('applist_history.html', data=data)
|
||||
|
||||
|
||||
@main.route('/appsobservatory/news')
|
||||
def appsobservatory_news():
|
||||
news_per_date = json.loads(open("./app/scripts/appListsHistory/news.json").read())
|
||||
return render_template('applist_news.html', news_per_date=list(reversed(list(news_per_date.items()))))
|
||||
|
||||
@main.route('/appsobservatory/news/rss')
|
||||
def appsobservatory_news_rss():
|
||||
rss_news_per_date = json.loads(open("./app/scripts/appListsHistory/news_rss.json").read())
|
||||
rss_xml = render_template('applist_news_rss.xml', rss_news_per_date=list(reversed(list(rss_news_per_date.items()))))
|
||||
response = make_response(rss_xml)
|
||||
response.headers['Content-Type'] = 'application/rss+xml'
|
||||
response.headers['Content-Disposition'] = "inline; filename=YNH_catalog_news.xml"
|
||||
return response
|
||||
|
||||
@main.app_template_filter()
|
||||
def format_datetime(value, format="%d %b %Y %I:%M %p"):
|
||||
if value is None:
|
||||
return ""
|
||||
return datetime.strptime(value, "%b %d %Y").strftime(format)
|
||||
|
||||
@main.route('/appsobservatory/unlisted')
|
||||
def appsobservatory_unlisted():
|
||||
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
{% if data.new %}
|
||||
<h2>New apps</h2>
|
||||
<ul>
|
||||
{% for app in data.new %}
|
||||
<li><a href="{{ app.url }}">{{ app.name.title() }}</a>
|
||||
({{ app.state }}{% if app.level %}, level {{ app.level }}{% endif %}) </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if data.improvements %}
|
||||
<h2>Improvements</h2>
|
||||
<ul>
|
||||
{% for app, changes in data.improvements %}
|
||||
<li><a href="{{ app.url }}">{{ app.name.title() }}</a>:
|
||||
{% for change in changes %}
|
||||
{% if change == "updated" %}
|
||||
Updated{{ "," if not loop.last }}
|
||||
{% elif change[0] == "state" %}
|
||||
State {{ change[1] }} -> {{ change[2] }}{{ "," if not loop.last }}
|
||||
{% elif change[0] == "level" %}
|
||||
Level {{ change[1] }} -> {{ change[2] }}{{ "," if not loop.last }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if data.updates %}
|
||||
<h2>Updates</h2>
|
||||
<ul>
|
||||
{% for app, changes in data.updates %}
|
||||
<li><a href="{{ app.url }}">{{ app.name.title() }}</a>:
|
||||
{% for change in changes %}
|
||||
{% if change == "updated" %}
|
||||
Updated{{ "," if not loop.last }}
|
||||
{% elif change[0] == "state" %}
|
||||
State {{ change[1] }} -> {{ change[2] }}{{ "," if not loop.last }}
|
||||
{% elif change[0] == "level" %}
|
||||
Level {{ change[1] }} -> {{ change[2] }}{{ "," if not loop.last }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if data.regressions %}
|
||||
<h2>Regressions</h2>
|
||||
<ul>
|
||||
{% for app, changes in data.regressions %}
|
||||
<li><a href="{{ app.url }}">{{ app.name.title() }}</a>:
|
||||
{% for change in changes %}
|
||||
{% if change == "updated" %}
|
||||
Updated{{ "," if not loop.last }}
|
||||
{% elif change[0] == "state" %}
|
||||
State {{ change[1] }} -> {{ change[2] }}{{ "," if not loop.last }}
|
||||
{% elif change[0] == "level" %}
|
||||
Level {{ change[1] }} -> {{ change[2] }}{{ "," if not loop.last }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if data.removed %}
|
||||
<h2>Apps removed</h2>
|
||||
<ul>
|
||||
{% for app in data.removed %}
|
||||
<li><a href="{{ app.url }}">{{ app.name.title() }}</a>
|
||||
({{ app.state }}{% if app.level %}, level {{ app.level }}{% endif %})
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
|
@ -1,8 +1,10 @@
|
|||
import toml
|
||||
import json
|
||||
import markdown
|
||||
import os
|
||||
import sys
|
||||
import inspect
|
||||
import requests
|
||||
from datetime import datetime
|
||||
|
||||
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
|
@ -148,7 +150,6 @@ def make_news():
|
|||
else:
|
||||
return int(lev)
|
||||
|
||||
|
||||
for d in time_points_until_today:
|
||||
d_label = d.strftime("%b %d %Y")
|
||||
|
||||
|
@ -167,19 +168,45 @@ def make_news():
|
|||
|
||||
news = news_per_date[d_label]
|
||||
for app in set(apps_previous_good & apps_current_broken):
|
||||
news["broke"].append((app, j[app]["url"]))
|
||||
news["broke"].append([app, j[app]["url"], j[app].get("branch", "master"), j[app].get("category", ""), j[app].get("subtags", "")])
|
||||
for app in set(apps_previous_broken & apps_current_good):
|
||||
news["repaired"].append((app, j[app]["url"]))
|
||||
news["repaired"].append([app, j[app]["url"], j[app].get("branch", "master"), j[app].get("category", ""), j[app].get("subtags", "")])
|
||||
for app in set(apps_current - apps_previous):
|
||||
news["added"].append((app, j[app]["url"]))
|
||||
news["added"].append([app, j[app]["url"], j[app].get("branch", "master"), j[app].get("category", ""), j[app].get("subtags", "")])
|
||||
for app in set(apps_previous - apps_current):
|
||||
news["removed"].append((app, previous_j[app]["url"]))
|
||||
news["removed"].append([app, previous_j[app]["url"], previous_j[app].get("branch", "master"), previous_j[app].get("category", ""), previous_j[app].get("subtags", "")])
|
||||
|
||||
previous_j = j
|
||||
|
||||
json.dump(news_per_date, open('news.json', 'w'))
|
||||
|
||||
# Generate json for RSS feed
|
||||
rss_number_of_times_points_to_include = 2
|
||||
rss_d_label = list(news_per_date)[-rss_number_of_times_points_to_include:]
|
||||
rss_feed = {k:news_per_date.get(k) for k in rss_d_label}
|
||||
|
||||
for d, status_list in rss_feed.items():
|
||||
print("Pushing all entries from " + d + " to RSS feed...")
|
||||
|
||||
for status, apps_list in status_list.items():
|
||||
for app in apps_list:
|
||||
# Memo: at this point, 'app' list's indexes correspond to [0] - app name, [1] - app url, [2] - app branch name, [3] - app category, [4] - app subtags
|
||||
|
||||
# Merge list of category and subtags into a unique string and store it in [3]
|
||||
if app[3] and app[4]:
|
||||
app[3] = app[3] + ", " + ", ".join(app[4])
|
||||
|
||||
# Retrieve app README and store it in [4]
|
||||
print("Retrieve Github README for app " + app[0])
|
||||
readme_url = "https://raw.githubusercontent.com/YunoHost-Apps/" + app[0] + "_ynh/" + app[2] + "/README.md"
|
||||
r = requests.get(readme_url)
|
||||
readme_md = r.text
|
||||
readme_md = readme_md.replace("./doc/screenshots/", "https://raw.githubusercontent.com/YunoHost-Apps/" + app[0] + "_ynh/" + app[2] + "/doc/screenshots/")
|
||||
readme_html = markdown.markdown(readme_md)
|
||||
app[4] = readme_html
|
||||
|
||||
json.dump(rss_feed, open('news_rss.json', 'w'))
|
||||
|
||||
def update_catalog_stats(app, history):
|
||||
|
||||
print(app)
|
||||
|
|
|
@ -66,3 +66,6 @@ td.ci-app-test-result > div.danger { background-color: rgb(225,80,62); }
|
|||
text-overflow: ellipsis;
|
||||
max-width:400px;
|
||||
}
|
||||
|
||||
.btn-rss { background-color: #ee802f; border-color: #ee802f; }
|
||||
.btn-rss:hover, .btn-rss:not(:disabled):not(.disabled):active { background-color: #ca630c; border-color: #c15b00; }
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-10 mx-3">
|
||||
<link rel="alternate" type="application/rss+xml" title="YNH Catalog News" href="{{ url_for('main.appsobservatory_news_rss')}}" />
|
||||
<a href="{{ url_for('main.appsobservatory_news_rss')}}" class = "btn btn-sm mb-3 py-2 px-3 btn-warning btn-rss text-uppercase font-weight-bold"><i class="oi oi-rss-alt pr-1" aria-hidden="true"></i>Suscribe via RSS</a>
|
||||
</div>
|
||||
|
||||
<div class="col-10 offset-1">
|
||||
|
||||
{% for date, news in news_per_date %}
|
||||
|
@ -9,28 +15,29 @@
|
|||
<h2>{{ date }}</h2>
|
||||
|
||||
<ul>
|
||||
{% for app, url in news["added"] %}
|
||||
{% for app in news["added"] %}
|
||||
{# MEMO: app list's indexes correspond to [0] - app name, [1] - app url, [2] - app Github branch name, [3] - app description (keywords), [4] - app readme in HTML #}
|
||||
<li>
|
||||
<span class="badge bg-primary" style="color: white;"><i class="oi oi-plus pr-1" aria-hidden="true"></i>Added</span>
|
||||
<a href="{{url}}">{{app}}</a>
|
||||
<a href="{{app[1]}}">{{app[0]}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for app, url in news["repaired"] %}
|
||||
{% for app in news["repaired"] %}
|
||||
<li>
|
||||
<span class="badge bg-success" style="color: white;"><i class="oi oi-circle-check pr-1" aria-hidden="true"></i>Repaired</span>
|
||||
<a href="{{url}}">{{app}}</a>
|
||||
<a href="{{app[1]}}">{{app[0]}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for app, url in news["broke"] %}
|
||||
{% for app in news["broke"] %}
|
||||
<li>
|
||||
<span class="badge bg-warning" style="color: white;"><i class="oi oi-warning pr-1" aria-hidden="true"></i>Broke</span>
|
||||
<a href="{{url}}">{{app}}</a>
|
||||
<a href="{{app[1]}}">{{app[0]}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for app, url in news["removed"] %}
|
||||
{% for app in news["removed"] %}
|
||||
<li>
|
||||
<span class="badge bg-danger" style="color: white;"><i class="oi oi-circle-x pr-1" aria-hidden="true"></i>Removed</span>
|
||||
<a href="{{url}}">{{app}}</a>
|
||||
<a href="{{app[1]}}">{{app[0]}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
31
app/templates/applist_news_rss.xml
Normal file
31
app/templates/applist_news_rss.xml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
|
||||
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
|
||||
>
|
||||
<channel>
|
||||
<title>YNH Catalog News</title>
|
||||
<link>{{ url_for('main.appsobservatory_news')}}</link>
|
||||
<atom:link href="{{ url_for('main.appsobservatory_news_rss')}}" rel="self" type="application/rss+xml" />
|
||||
<description>YunoHost apps catalog's news</description>
|
||||
{%- for date, status_list in rss_news_per_date %}
|
||||
{%- for status in ("added", "repaired", "broke", "removed") %}
|
||||
{%- for app in status_list[status] %}
|
||||
{#- MEMO: app list's indexes correspond to [0] - app name, [1] - app url, [2] - app Github branch name, [3] - app description (keywords), [4] - app readme in HTML #}
|
||||
<item>
|
||||
<title>[{{ status|upper }}] {{ app[0]|capitalize }}</title>
|
||||
<link>{{ app[1] }}</link>
|
||||
<guid>{{ app[1] }}#{{ date|format_datetime("%Y%m%d") }}</guid>
|
||||
<pubDate>{{ date|format_datetime("%a, %d %b %Y %H:%M:%S +0000") }}</pubDate>
|
||||
<description>{{ app[3]|capitalize }}</description>
|
||||
<content:encoded><![CDATA[{{ app[4] }}]]></content:encoded>
|
||||
</item>
|
||||
{% endfor -%}
|
||||
{% endfor -%}
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
Loading…
Add table
Reference in a new issue