-
Notifications
You must be signed in to change notification settings - Fork 1
/
rfdwatch.py
115 lines (85 loc) · 3.43 KB
/
rfdwatch.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
import click
import os
import sendgrid
import sqlite3
import time
import urllib.request
from bs4 import BeautifulSoup
from sendgrid.helpers.mail import *
HOURS_TO_STORE = 24
DEFAULT_DB_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'rfdwatch.db')
def hours_to_seconds(hours):
return hours * 3600
def get_matching_keyword(s, keywords):
for k in keywords:
if k.lower() in s.lower():
return k
return None
def send_alert(keyword, topic_link, email):
title = topic_link.get_text().strip()
link = 'https://forums.redflagdeals.com' + topic_link.get('href')
sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY'))
from_email = Email(email)
to_email = Email(email)
subject = 'RFDWatch – Match for keyword "{}" found!'.format(keyword)
content = Content('text/html', 'RFD Link: <a href="{}">{}</a>'.format(link, title))
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())
print('Email sent to {}'.format(email))
print(response.status_code)
print(response.body)
print(response.headers)
def db_contains(keyword, url_path, db_path=DEFAULT_DB_PATH):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('''SELECT count(*) FROM matches WHERE keyword = ? AND url_path = ?''', (keyword, url_path))
contains = cursor.fetchone()[0] > 0
conn.close()
return contains
def store_match(keyword, url_path, db_path=DEFAULT_DB_PATH):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
conn.execute('''INSERT INTO matches(keyword, url_path, timestamp) VALUES (?, ?, ?)''', (keyword, url_path, int(time.time())))
conn.commit()
conn.close()
@click.group()
def cli():
pass
@cli.command('setupdb')
@click.option('--path', '-p', default=DEFAULT_DB_PATH)
def setup_db(path):
conn = sqlite3.connect(path)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE matches (keyword text, url_path text, timestamp integer)''')
conn.commit()
conn.close()
print("DB created at {}".format(DEFAULT_DB_PATH))
@cli.command('cleandb')
@click.option('--path', '-p', default=DEFAULT_DB_PATH)
@click.option('--hours', '-h', default=12)
def clean_db(path, hours):
conn = sqlite3.connect(path)
cursor = conn.cursor()
oldest_time = int(time.time()) - hours_to_seconds(hours)
n = cursor.execute('''DELETE FROM matches WHERE timestamp <= ?''', (oldest_time,)).rowcount
conn.commit()
conn.close()
if n > 0:
print("{} matches deleted".format(n))
@cli.command('watch')
@click.argument('email')
@click.argument('keywords') # space delimited
@click.pass_context
def rfdwatch(ctx, email, keywords):
ctx.invoke(clean_db)
rfd_soup = BeautifulSoup(urllib.request.urlopen("https://forums.redflagdeals.com/hot-deals-f9/").read(), "html.parser")
topic_links = rfd_soup.select('.topiclist .topic_title_link')
for topic_link in topic_links:
title = topic_link.get_text().strip()
matching_keyword = get_matching_keyword(title, keywords.split())
if matching_keyword is not None and not db_contains(matching_keyword, topic_link.get('href')):
print('keyword "{}" found, sending alert email to {}'.format(matching_keyword, email))
send_alert(matching_keyword, topic_link, email)
store_match(matching_keyword, topic_link.get('href'))
if __name__ == '__main__':
cli()