-
Notifications
You must be signed in to change notification settings - Fork 2
/
dbutils.py
234 lines (215 loc) · 7.38 KB
/
dbutils.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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import mysql.connector
from mysql.connector import errorcode
import json
import os
import sys
import requests
import re
import nltk
class DbAccess(object):
"""Access database
"""
def __init__(self, db_name, usr, pwd=None):
self.db_name = db_name
self.db_url = "couchtubedb.clctie6ngr4h.us-west-1.rds.amazonaws.com"
self.connect(usr, pwd)
self.cursor = self.cnx.cursor()
def connect(self, usr, pwd=None):
"""Try to connect to DB
"""
try:
self.cnx = mysql.connector.connect(user=usr, password=pwd,
database=self.db_name, host=self.db_url)
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("Something is wrong with your user name or password")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("Database does not exists")
else:
print(err)
sys.exit(1)
def close(self):
"""Disconnect from DB
"""
self.cursor.close()
self.cnx.close()
class DbGet(DbAccess):
"""Retrieve data from MySQL DB"""
def __init__(self):
usr = os.environ['usr_read']
super(DbGet, self).__init__('couchtube', usr)
def get_shows(self):
"""Get all shows in DB, sorted by YT #videos found
"""
query = ("""
SELECT title, year, poster, episodes, ytcount,
(episodes - ytLicensed)/episodes*100 as ppay,
ytcount/episodes as ytrep,
runtime, title_iso, img
FROM series
ORDER BY ytrep DESC
""")
self.cursor.execute(query)
shows = [s for s in self.cursor]
# for s in self.cursor:
# imgblob = s[9].decode('base64')
# s = list(s)
# s[9] = imgblob
# shows.append(tuple(s))
return shows
def get_episodes(self, show, year):
"""Get all episodes of a given show
"""
query = ("""
SELECT title, season, episode, ytId, thumb
FROM episodes
WHERE series_title=%s
AND series_year=%s
ORDER BY season, episode
""")
self.cursor.execute(query, (show, year))
return [s for s in self.cursor]
def get_completeness(self, show, year):
"""Return the completeness of a show, and the list of episodes
"""
out = {'episodes': 0,
'found': [],
'free': []}
query = ("""
SELECT season, episode, paid, ytId
FROM episodes
WHERE series_title=%s
AND series_year=%s
ORDER BY season, episode
""")
self.cursor.execute(query, (show, year))
data = self.cursor.fetchall()
out['episodes'] = len(data)
out['found'] = [i+1 for i,el in enumerate(data)
if el[3] is not None]
out['free'] = [i+1 for i,el in enumerate(data)
if el[3] is not None
and el[2]==0]
return out
def check_title(self, show_title):
"""Check if a show is in the database, allowing for messy entries
"""
lancaster = nltk.LancasterStemmer()
show_title_stem = [lancaster.stem(t) \
for t in nltk.regexp_tokenize(show_title, r"\w+")]
show_title_reg = ''
for w in show_title_stem:
show_title_reg += '%s%% ' % w
query = ("""
SELECT title
FROM series
WHERE TRIM(LOWER(title)) LIKE %s
LIMIT 1
""")
self.cursor.execute(query, (show_title_reg.strip()))
data = self.cursor.fetchall()
if self.cursor.rowcount > 0:
return data[0]
else:
return
class DbPut(DbAccess):
"""Retrieve data from MySQL DB
"""
def __init__(self):
usr = os.environ['usr_write']
pwd = os.environ['pwd_write']
super(DbPut, self).__init__('couchtube', usr, pwd)
def put_show(self, show):
"""Add a show to the series table
"""
query = ("INSERT INTO series "
" (title, episodes, poster, rating, year, runtime, img, title_iso) "
" VALUES (%s, %s, %s, %s, %s, %s, %s, %s) "
" ON DUPLICATE KEY UPDATE "
" title=VALUES(title), "
" episodes=VALUES(episodes), "
" rating=VALUES(rating), "
" poster=VALUES(poster), "
" year=VALUES(year), "
" runtime=VALUES(runtime), "
" img=VALUES(img), "
" title_iso=VALUES(title_iso) ")
params = (
show['title'],
show['episodes'],
show['poster'],
show['rating'],
show["year"],
show["runtime"],
requests.get(show['poster']).content.encode('base64'),
''.join(re.findall('(\w+|\d)',
show['title'].lower() + str(show['year']))))
self.cursor.execute(query, params)
self.cnx.commit()
return True
def put_episodes(self, show, year, episodes):
"""Add a show to the series table
"""
query = ("INSERT INTO episodes "
" (series_title, series_year, season, episode, title) "
" VALUES (%s, %s, %s, %s, %s) "
" ON DUPLICATE KEY UPDATE "
" series_title=VALUES(series_title), "
" series_year=VALUES(series_year), "
" episode=VALUES(episode), "
" season=VALUES(season), "
" title=VALUES(title) ")
params = [
(show, year,
key[0], key[1],
name) for key, name in episodes.items()]
self.cursor.executemany(query, params)
self.cnx.commit()
return True
def update_show(self, show, year, field, value):
"""Update series table with field value
"""
query = ("""
UPDATE series
SET {0:}=%s
WHERE title=%s AND year=%s;
""".format(field))
params = (value, show, year)
self.cursor.execute(query, params)
self.cnx.commit()
return True
def update_episode(self, show, year,
se_number, ep_number, field, value):
"""Update episodes table with field value
"""
query = ("""
UPDATE episodes
SET {0:}=%s
WHERE series_title=%s AND series_year=%s
AND episode=%s AND season=%s;
""".format(field))
params = (value, show, year,
ep_number, se_number)
self.cursor.execute(query, params)
self.cnx.commit()
return True
def remove_show(self, show, year):
"""Remove all data for given show
"""
# First delite episodes
query = ("""
DELETE FROM episodes
WHERE series_title=%s AND series_year=%s;
""")
params = (show, year)
self.cursor.execute(query, params)
self.cnx.commit()
# Then delete show info
query = ("""
DELETE FROM series
WHERE title=%s AND year=%s;
""")
params = (show, year)
self.cursor.execute(query, params)
self.cnx.commit()
return True