💾 Archived View for elpamplina.duckdns.org › programacion › descargas › mastonewsfeed.py captured on 2024-08-25 at 00:58:29.

View Raw

More Information

⬅️ Previous capture (2024-06-16)

-=-=-=-=-=-=-

# Copyright 2024 El Pamplina <elpamplinadecai@gmail.com>

# MastoNewsFeed is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# MastoNewsFeed is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# <http://www.gnu.org/licenses/>.


import logging
import sys
from wsgiref import simple_server
import falcon
import requests
from falcon import HTTPNotFound, HTTPInternalServerError
from feedgen.feed import FeedGenerator
from requests import JSONDecodeError

VERSION = '0.0.1'

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logger = logging.getLogger('mastonewsfeed')
logger.info(f"MastoNewsFeed version {VERSION}")


class MastoNewsFeed:
    def on_get(self, req, resp):
        logger.debug(f'GET params: {req.params}')
        server_param = req.params.get('server')
        server_list = server_param if type(server_param) == list else [server_param, ]
        format = req.params.get('format', 'RSS').upper()
        logger.info(f"Getting feed from {server_list}")
        feed_unsorted = []
        for server in server_list:
            if server:
                logger.debug(f'Making GET request for {server}')
                raw = requests.get(f"https://{server}/api/v1/trends/links")
                logger.debug(f"Response: {raw.status_code} {raw.reason}")
                if raw.status_code == 200:
                    try:
                        server_feed = raw.json()
                        logger.debug("Valid JSON response")
                        logger.info(f"Got {len(server_feed)} items from {server}")
                        feed_unsorted.extend(server_feed)
                    except JSONDecodeError:
                        logger.error("Error decoding JSON response")
            else:
                raise HTTPInternalServerError()
        if feed_unsorted:
            feed = sorted(feed_unsorted, key=lambda entry: entry['published_at'] if entry['published_at'] is not None else '0', reverse=True)
            logger.debug('Inserting general info')
            fg = FeedGenerator()
            fg.title('Mastodon News Feed')
            fg.link(href=req.uri)
            fg.id(req.uri)
            fg.description(f'News bundle from Mastodon server {server}')
            fg.generator(f'MastoNewsFeed {VERSION}')
            for item in feed:
                if item['type'] == 'link':
                    logger.debug(f"Inserting item: {item['url']}")
                    fe = fg.add_item()
                    fe.id(item['url'])
                    fe.title(item['title'])
                    fe.summary(item['description'])
                    fe.link(href=item['url'])
                    fe.author(name=item['author_name'])
                    fe.pubDate(item['published_at'])
                    logger.debug(item['published_at'])
            if format == 'ATOM':
                logger.debug('Generating Atom feed')
                resp.text = fg.atom_str(pretty=True)
            else:
                logger.debug('Generating RSS feed')
                resp.text = fg.rss_str(pretty=True)
            resp.content_type = falcon.MEDIA_XML
        else:
            raise HTTPNotFound()
        logger.debug('Request finished')


app = falcon.App()
app.add_route('/', MastoNewsFeed())

if __name__ == '__main__':
    httpd = simple_server.make_server('0.0.0.0', 8000, app)
    logger.warning(f"Server running on development mode on port {httpd.server_port}")
    httpd.serve_forever()