summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDashie <dashie@sigpipe.me>2020-04-06 17:20:17 +0200
committerDashie <dashie@sigpipe.me>2020-04-06 17:20:17 +0200
commit465ad01956169c1b95a19f48790a5b3bc387ee25 (patch)
tree8d0ea154a8d7c6188439f1dc7e89b7d733d0cbd9
parent9fa5988bfe144c0caea48cdf8c6c54216b650a52 (diff)
Add support for feeds in Actor for funkwhale; Also add RSS to feeds
-rw-r--r--api/controllers/feeds.py48
-rw-r--r--api/models.py11
2 files changed, 48 insertions, 11 deletions
diff --git a/api/controllers/feeds.py b/api/controllers/feeds.py
index 5da30713..32004008 100644
--- a/api/controllers/feeds.py
+++ b/api/controllers/feeds.py
@@ -3,13 +3,15 @@ from models import User, Sound, Album
from utils.defaults import Reel2bitsDefaults
from feedgen.feed import FeedGenerator
import pytz
+import sqlalchemy
bp_feeds = Blueprint("bp_feeds", __name__)
-def gen_feed(title, author, feed_url, url, subtitle, logo, categories=None, album=False, licenses=False):
+def gen_feed(title, author, feed_url, url, subtitle, logo, categories=None, album=False, licenses=False, typ="atom"):
fg = FeedGenerator()
- fg.load_extension("podcast")
+ if typ != "rss":
+ fg.load_extension("podcast")
fg.id(feed_url)
fg.title(title)
@@ -23,13 +25,15 @@ def gen_feed(title, author, feed_url, url, subtitle, logo, categories=None, albu
generator="reel2bits", uri=f"https://{current_app.config['AP_DOMAIN']}", version=g.cfg["REEL2BITS_VERSION"]
)
- if album and categories:
+ if album and categories and typ != "rss":
fg.podcast.itunes_category(categories[0])
fg.category([{"term": c, "label": c} for c in categories])
if licenses:
fg.rights("See individual tracks: " + ", ".join(licenses))
+ print(typ)
+
return fg
@@ -38,12 +42,18 @@ def utcdate(date):
@bp_feeds.route("/feeds/tracks/<string:user_id>", methods=["GET"])
-@bp_feeds.route("/feeds/tracks/<string:user_id>.atom", methods=["GET"])
+@bp_feeds.route("/feeds/tracks/<string:user_id>.atom", methods=["GET"], endpoint="tracks_atom")
+@bp_feeds.route("/feeds/tracks/<string:user_id>.rss", methods=["GET"], endpoint="tracks_rss")
def tracks(user_id):
- user = User.query.filter(User.flake_id == user_id).first()
+ try:
+ user = User.query.filter(User.flake_id == user_id).first()
+ except sqlalchemy.exc.DataError:
+ abort(500)
if not user:
abort(404)
+ typ = "rss" if request.endpoint in ["bp_feeds.tracks_rss"] else "atom"
+
q = Sound.query.filter(Sound.user_id == user.id, Sound.private.is_(False))
q = q.filter(Sound.transcode_state == Sound.TRANSCODE_DONE)
q = q.order_by(Sound.uploaded.desc())
@@ -53,7 +63,7 @@ def tracks(user_id):
author = {"name": user.name, "uri": f"https://{current_app.config['AP_DOMAIN']}/{user.name}"}
logo = None or f"https://{current_app.config['AP_DOMAIN']}/static/userpic_placeholder.png"
- feed = gen_feed(f"{user.name} tracks", author, feed_url, url, f"Tracks of {user.name}", logo)
+ feed = gen_feed(f"{user.name} tracks", author, feed_url, url, f"Tracks of {user.name}", logo, typ=typ)
for track in q:
path_sound = track.path_sound(orig=False)
@@ -73,19 +83,31 @@ def tracks(user_id):
fe.pubDate(utcdate(track.uploaded))
fe.updated(utcdate(track.updated))
fe.content(track.description)
- return feed.atom_str(pretty=True)
+ if typ == "rss":
+ return feed.rss_str(pretty=True)
+ else:
+ return feed.atom_str(pretty=True)
@bp_feeds.route("/feeds/album/<string:user_id>/<int:album_id>", methods=["GET"])
-@bp_feeds.route("/feeds/album/<string:user_id>/<int:album_id>.atom", methods=["GET"])
+@bp_feeds.route("/feeds/album/<string:user_id>/<int:album_id>.atom", methods=["GET"], endpoint="album_atom")
+@bp_feeds.route("/feeds/album/<string:user_id>/<int:album_id>.rss", methods=["GET"], endpoint="album_rss")
def album(user_id, album_id):
- user = User.query.filter(User.flake_id == user_id).first()
+ try:
+ user = User.query.filter(User.flake_id == user_id).first()
+ except sqlalchemy.exc.DataError:
+ abort(500)
if not user:
abort(404)
- album = Album.query.filter(Album.id == album_id, Album.user_id == user.id, Album.private.is_(False)).first()
+ try:
+ album = Album.query.filter(Album.id == album_id, Album.user_id == user.id, Album.private.is_(False)).first()
+ except sqlalchemy.exc.DataError:
+ abort(500)
if not album:
abort(404)
+ typ = "rss" if request.endpoint in ["bp_feeds.album_rss"] else "atom"
+
feed_url = request.url
url = f"https://{current_app.config['AP_DOMAIN']}/{user.name}/album/{album.title}"
author = {"name": user.name, "uri": f"https://{current_app.config['AP_DOMAIN']}/{user.name}"}
@@ -114,6 +136,7 @@ def album(user_id, album_id):
categories=categories,
album=True,
licenses=lics,
+ typ=typ,
)
for track in album.sounds.filter(Sound.transcode_state == Sound.TRANSCODE_DONE):
@@ -135,4 +158,7 @@ def album(user_id, album_id):
fe.updated(utcdate(track.updated))
fe.content(track.description)
fe.category([{"term": c, "label": c} for c in [track.genre]])
- return feed.atom_str(pretty=True)
+ if typ == "rss":
+ return feed.rss_str(pretty=True)
+ else:
+ return feed.atom_str(pretty=True)
diff --git a/api/models.py b/api/models.py
index d057d6b1..42ec3de9 100644
--- a/api/models.py
+++ b/api/models.py
@@ -669,6 +669,8 @@ class Actor(db.Model):
url_avatar = url_for("get_uploads_stuff", thing="avatars", stuff=self.user.path_avatar(), _external=True)
else:
url_avatar = f"{current_app.config['REEL2BITS_URL']}/static/userpic_placeholder.svg"
+ url_feed_atom = url_for("bp_feeds.tracks_atom", user_id=self.user.flake_id, _external=True)
+ url_feed_rss = url_for("bp_feeds.tracks_rss", user_id=self.user.flake_id, _external=True)
return {
"@context": DEFAULT_CTX,
@@ -684,6 +686,15 @@ class Actor(db.Model):
"publicKey": {"id": self.private_key_id(), "owner": self.url, "publicKeyPem": self.public_key},
"endpoints": {"sharedInbox": self.shared_inbox_url},
"icon": {"type": "Image", "url": url_avatar},
+ "url": [
+ {
+ "type": "Link",
+ "mediaType": "text/html",
+ "href": f"{current_app.config['REEL2BITS_URL']}/user/{self.preferred_username}",
+ },
+ {"type": "Link", "mediaType": "application/atom+xml", "href": url_feed_atom},
+ {"type": "Link", "mediaType": "application/atom+xml", "href": url_feed_rss},
+ ],
}