-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
188 lines (161 loc) · 6.52 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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import os
import requests
import sentry_sdk
from typing import Union
from flask import Flask, request, Response, send_from_directory, send_file
from urllib.parse import unquote, urlparse
from rss_lambda.simple_filters.simple_filters import \
filter_by_title_including_substrings,\
filter_by_title_excluding_substrings,\
filter_by_description_including_substrings,\
filter_by_description_excluding_substrings,\
filter_by_description_containing_image
from rss_lambda.utils.rss_lambda_error import RSSLambdaError
from rss_lambda.image_recog.image_recog import image_recog
from rss_lambda.merger.merger import merger
from rss_lambda.to_image_feed.to_image_feed import to_image_feed
if os.getenv('SENTRY_DSN'):
print("Sentry enabled")
sentry_sdk.init(dsn=os.getenv('SENTRY_DSN'))
else:
print("Sentry disabled")
max_params = 50
app = Flask(__name__)
@app.route("/")
def index():
return send_from_directory('static', 'index.html')
def download_feed(rss_url: str, headers) -> Union[str, Response]:
try:
res = requests.get(rss_url, headers={
'User-Agent': headers.get('User-Agent', '')
})
if res.status_code >= 400 and res.status_code < 600:
return Response(res.content, res.status_code)
return res.text
except Exception as _:
return Response("Failed to download the feed", 500)
@app.route("/rss")
def _rss():
# parse url
url = request.args.get('url', default=None)
if not url:
return "No url provided", 400
url = unquote(url)
parsed_url = urlparse(url)
if not all([parsed_url.scheme, parsed_url.netloc]):
return "Invalid url", 400
# parse op
op = request.args.get('op', default=None)
if not op:
return "No op provided", 400
params = request.args.getlist('param')
if len(params) > max_params:
return f"Too many params, max {max_params} params allowed", 400
try:
if op == "filter_title_incl_substrs":
if not params:
return "No param provided", 400
rss_text_or_res = download_feed(url, request.headers)
if isinstance(rss_text_or_res, str):
return Response(filter_by_title_including_substrings(rss_text_or_res, params), mimetype='application/xml')
return rss_text_or_res
elif op == "filter_title_excl_substrs":
if not params:
return "No param provided", 400
rss_text_or_res = download_feed(url, request.headers)
if isinstance(rss_text_or_res, str):
return Response(filter_by_title_excluding_substrings(rss_text_or_res, params), mimetype='application/xml')
return rss_text_or_res
elif op == "filter_desc_incl_substrs":
if not params:
return "No param provided", 400
rss_text_or_res = download_feed(url, request.headers)
if isinstance(rss_text_or_res, str):
return Response(filter_by_description_including_substrings(rss_text_or_res, params), mimetype='application/xml')
return rss_text_or_res
elif op == "filter_desc_excl_substrs":
if not params:
return "No param provided", 400
rss_text_or_res = download_feed(url, request.headers)
if isinstance(rss_text_or_res, str):
return Response(filter_by_description_excluding_substrings(rss_text_or_res, params), mimetype='application/xml')
return rss_text_or_res
elif op == "filter_desc_cont_img":
if params:
return "No param expected", 400
rss_text_or_res = download_feed(url, request.headers)
if isinstance(rss_text_or_res, str):
return Response(filter_by_description_containing_image(rss_text_or_res), mimetype='application/xml')
return rss_text_or_res
else:
return f"Unknown op {op}", 400
except RSSLambdaError as e:
return e.message, 500
@app.route("/rss_image_recog")
def _rss_image_recog():
# parse url
url = request.args.get('url', default=None)
if not url:
return "No url provided", 400
url = unquote(url)
parsed_url = urlparse(url)
if not all([parsed_url.scheme, parsed_url.netloc]):
return "Invalid url", 400
rss_text_or_res = download_feed(url, request.headers)
if not isinstance(rss_text_or_res, str):
return rss_text_or_res
# parse class_id
class_id = request.args.get('class_id', default=None)
if not class_id:
return "No class_id provided", 400
# Hack for Reeder (iOS)
if class_id.endswith("/rss"):
class_id = class_id[:-4]
if class_id.endswith("/feed"):
class_id = class_id[:-5]
class_id = int(class_id)
try:
return Response(image_recog(rss_text_or_res, class_id, url), mimetype='application/xml')
except RSSLambdaError as e:
return e.message, 500
@app.route("/rss_merger")
def _rss_merger():
# parse urls
urls = request.args.getlist('url')
if not urls:
return "No url provided", 400
if len(urls) == 1:
return "At least two urls are required", 400
urls = [unquote(url) for url in urls]
for url in urls:
parsed_url = urlparse(url)
if not all([parsed_url.scheme, parsed_url.netloc]):
return "Invalid url", 400
rss_texts = [download_feed(url, request.headers) for url in urls]
for rss_text_or_res in rss_texts:
if not isinstance(rss_text_or_res, str):
return rss_text_or_res
try:
return Response(merger(rss_texts), mimetype='application/xml')
except RSSLambdaError as e:
return e.message, 500
@app.route("/to_image_feed")
def _to_image_feed():
# parse url
url = request.args.get('url', default=None)
if not url:
return "No url provided", 400
url = unquote(url)
parsed_url = urlparse(url)
if not all([parsed_url.scheme, parsed_url.netloc]):
return "Invalid url", 400
rss_text_or_res = download_feed(url, request.headers)
if not isinstance(rss_text_or_res, str):
return rss_text_or_res
try:
return Response(to_image_feed(rss_text_or_res), mimetype='application/xml')
except RSSLambdaError as e:
return e.message, 500
@app.route("/test_rss")
def _test_rss():
return send_file('test-rss.xml', 'application/xml')