diff --git a/activitypub.py b/activitypub.py index 51557fa..9185745 100644 --- a/activitypub.py +++ b/activitypub.py @@ -523,8 +523,8 @@ def gen_feed(): fg.logo(ME.get("icon", {}).get("url")) fg.language("en") for item in DB.activities.find( - {"box": Box.OUTBOX.value, "type": "Create"}, limit=50 - ): + {"box": Box.OUTBOX.value, "type": "Create", "meta.deleted": False}, limit=10 + ).sort("_id", -1): fe = fg.add_entry() fe.id(item["activity"]["object"].get("url")) fe.link(href=item["activity"]["object"].get("url")) @@ -537,11 +537,11 @@ def json_feed(path: str) -> Dict[str, Any]: """JSON Feed (https://jsonfeed.org/) document.""" data = [] for item in DB.activities.find( - {"box": Box.OUTBOX.value, "type": "Create"}, limit=50 - ): + {"box": Box.OUTBOX.value, "type": "Create", "meta.deleted": False}, limit=10 + ).sort("_id", -1): data.append( { - "id": item["id"], + "id": item["activity"]["id"], "url": item["activity"]["object"].get("url"), "content_html": item["activity"]["object"]["content"], "content_text": html2text(item["activity"]["object"]["content"]), diff --git a/app.py b/app.py index 30c8241..0730813 100644 --- a/app.py +++ b/app.py @@ -189,7 +189,10 @@ ALLOWED_TAGS = [ def clean_html(html): - return bleach.clean(html, tags=ALLOWED_TAGS) + try: + return bleach.clean(html, tags=ALLOWED_TAGS) + except: + return "" _GRIDFS_CACHE: Dict[Tuple[Kind, str, Optional[int]], str] = {} @@ -282,9 +285,12 @@ def domain(url): @app.template_filter() def url_or_id(d): - if "url" in d: - return d["url"] - return d["id"] + if isinstance(d, dict): + if ("url" in d) and isinstance(d["url"], str): + return d["url"] + else: + return d["id"] + return "" @app.template_filter() @@ -367,7 +373,9 @@ def _is_img(filename): @app.template_filter() def not_only_imgs(attachment): for a in attachment: - if not _is_img(a["url"]): + if isinstance(a, dict) and not _is_img(a["url"]): + return True + if isinstance(a, str) and not _is_img(a): return True return False @@ -961,7 +969,10 @@ def _build_thread(data, include_children=True): ): _flatten(snode, level=level + 1) - _flatten(idx[root_id]) + try: + _flatten(idx[root_id]) + except KeyError: + app.logger.info(f"{root_id} is not there! skipping") return thread @@ -1524,7 +1535,15 @@ def _user_api_arg(key: str, **kwargs): def _user_api_get_note(from_outbox: bool = False): oid = _user_api_arg("id") app.logger.info(f"fetching {oid}") - note = ap.parse_activity(get_backend().fetch_iri(oid), expected=ActivityType.NOTE) + try: + note = ap.parse_activity(get_backend().fetch_iri(oid), expected=ActivityType.NOTE) + except: + try: + note = ap.parse_activity(get_backend().fetch_iri(oid), expected=ActivityType.VIDEO) + except: + raise ActivityNotFoundError( + "Expected Note or Video ActivityType, but got something else" + ) if from_outbox and not note.id.startswith(ID): raise NotFromOutboxError( f"cannot load {note.id}, id must be owned by the server" @@ -1876,12 +1895,8 @@ def followers(): ) raw_followers, older_than, newer_than = paginated_query(DB.activities, q) - followers = [] - for doc in raw_followers: - try: - followers.append(doc["meta"]["actor"]) - except Exception: - pass + followers = [doc["meta"]["actor"] + for doc in raw_followers if "actor" in doc.get("meta", {})] return render_template( "followers.html", followers_data=followers, @@ -1909,7 +1924,9 @@ def following(): abort(404) following, older_than, newer_than = paginated_query(DB.activities, q) - following = [(doc["remote_id"], doc["meta"]["object"]) for doc in following] + following = [(doc["remote_id"], doc["meta"]["object"]) + for doc in following + if "remote_id" in doc and "object" in doc.get("meta", {})] return render_template( "following.html", following_data=following, @@ -2070,7 +2087,7 @@ def indieauth_flow(): return redirect(red) -# @app.route('/indieauth', methods=['GET', 'POST']) +@app.route('/indieauth', methods=['GET', 'POST']) def indieauth_endpoint(): if request.method == "GET": if not session.get("logged_in"): @@ -2167,3 +2184,29 @@ def token_endpoint(): "client_id": payload["client_id"], } ) + + +@app.route("/feed.json") +def json_feed(): + return Response( + response=json.dumps( + activitypub.json_feed("/feed.json") + ), + headers={"Content-Type": "application/json"}, + ) + + +@app.route("/feed.atom") +def atom_feed(): + return Response( + response=activitypub.gen_feed().atom_str(), + headers={"Content-Type": "application/atom+xml"}, + ) + + +@app.route("/feed.rss") +def rss_feed(): + return Response( + response=activitypub.gen_feed().rss_str(), + headers={"Content-Type": "application/rss+xml"}, + ) diff --git a/sass/base_theme.scss b/sass/base_theme.scss index 17fa02c..b878a19 100644 --- a/sass/base_theme.scss +++ b/sass/base_theme.scss @@ -40,10 +40,11 @@ a:hover { .lcolor { color: $color-light; } -.older-link, .newer-linker, .older-link:hover, .newer-link:hover { +.older-link, .newer-link, .older-link:hover, .newer-link:hover { text-decoration: none; padding: 3px; } +.older-link { float: left } .newer-link { float: right } .clear { clear: both; } .remote-follow-button { @@ -210,6 +211,7 @@ a:hover { .note-wrapper { flex: 1; padding-left: 15px; + overflow: hidden; } .bottom-bar { margin-top:10px; } diff --git a/templates/index.html b/templates/index.html index 1331a1f..13a488c 100644 --- a/templates/index.html +++ b/templates/index.html @@ -34,6 +34,7 @@ {% for item in outbox_data %} {% if item | has_type('Announce') %} + {% if "actor" in item.meta %} {% set boost_actor = item.meta.actor %} {% if session.logged_in %}