-
Notifications
You must be signed in to change notification settings - Fork 2
/
app.py
125 lines (113 loc) · 4.29 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import requests
import os
import secrets
from datetime import datetime
from dotenv import load_dotenv
from feedgen.feed import FeedGenerator
from flask import Flask, request, make_response, render_template, flash
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from urllib.parse import quote_plus, unquote
app = Flask(__name__)
app.secret_key = secrets.token_hex() # No need to persist this key between resets
load_dotenv()
DIFFBOT_TOKEN = os.getenv("DIFFBOT_TOKEN", None)
# Really basic rate limiting to avoid taking down the app by bad actors
limiter = Limiter(
get_remote_address,
app=app,
storage_uri='memory:https://'
)
@app.route('/')
def index():
return render_template('home.html')
@app.route('/feeds')
def feeds():
feed_sample = []
feed_detail = {}
actual_rss_url = ""
try:
# Attempt to Generate an RSS Feed
fg, actual_rss_url = generate_feed(request.args.get('url', None))
# Feed Details
feed_detail = {
"title": fg.title(),
"description": fg.description(),
"link": fg.link(),
"icon": fg.icon()
}
except Exception as e:
flash(str(e), 'Error')
return render_template('home.html', page_url=request.args.get('url', ''), feed_detail=feed_detail, actual_rss_url=actual_rss_url)
@app.route('/rss')
@limiter.limit("1/second", error_message='Rate limit exceeded')
def rss():
try:
fg, rss_url = generate_feed(request.args.get('url', None))
response = make_response(fg.rss_str())
response.headers.set('Content-Type', 'application/rss+xml')
return response
except Exception as e:
return make_response(str(e), 400)
@app.route('/atom')
@limiter.limit("1/second", error_message='Rate limit exceeded')
def atom():
try:
fg, rss_url = generate_feed(request.args.get('url', None))
response = make_response(fg.atom_str())
response.headers.set('Content-Type', 'application/atom+xml')
return response
except Exception as e:
return make_response(str(e), 400)
def generate_feed(url):
# 1. Extract list from URL
list_url = url
feed_items = []
feed_title = ""
feed_description = ""
feed_icon= ""
feed_url = ""
actual_rss_url = None
if not list_url:
raise Exception("No URL Provided")
try:
payload = {
'token': DIFFBOT_TOKEN,
'url': unquote(list_url)
}
extracted_list_response = requests.get(f"https://api.diffbot.com/v3/list", params=payload)
extracted_list = extracted_list_response.json()
if extracted_list.get("error", None):
raise Exception(extracted_list.get("error", "Page Error"))
feed_items = extracted_list.get("objects", [])[0].get("items", [])
feed_title = extracted_list.get("objects", [])[0].get("title", feed_url)
feed_description = extracted_list.get("objects", [])[0].get("pageUrl", "")
feed_icon = extracted_list.get("objects", [])[0].get("icon", "")
feed_url = extracted_list.get("objects", [])[0].get("pageUrl", "")
actual_rss_url = extracted_list.get("objects", [])[0].get("rss_url", None)
except Exception as e:
print("Exception: ", e)
raise Exception(str(e))
# 2. Instantiate a Feed
fg = FeedGenerator()
fg.title(feed_title if feed_title else feed_url)
fg.id(feed_url)
fg.description(feed_description)
fg.icon(feed_icon)
fg.link(href=f"https://rss.diffbot.com/rss?url={feed_url}", rel='self')
fg.link(href=feed_url, rel='alternate')
fg.managingEditor(managingEditor="[email protected] (Jerome Choo)")
fg.docs(docs="https://rss.diffbot.com")
# 3. Generate feed item from list items
for article in feed_items:
if article.get("title", None) and article.get("link", None):
fe = fg.add_entry()
fe.title(article.get("title", ""))
fe.id(article.get("link", ""))
fe.link(href=article.get("link", ""))
fe.description(article.get("summary", ""))
if author := article.get("byline", None) or article.get("author", None):
fe.author(name=author)
if published_date := article.get("date", None):
fe.pubDate(published_date)
return fg, actual_rss_url