-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDatabase.rb
302 lines (241 loc) · 10.4 KB
/
Database.rb
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
module MyTV
class Database
# Add a new show and its episodes. Receives a string and the dataset my_shows and episodes as parameters
def Database.add_show(shows, dataset2, show_name, verbose=true)
# Finding the show
obj = Web.search_show(show_name)
$logger.debug "Trying to add show <#{obj['name']}>"
# Checks it's not in the database already
if shows.where(:show_id => obj['id']).count == 1
$logger.warn "The show <#{obj['name']}> is already in the database"
puts "The show #{obj['name']} is already in the database" unless !verbose
else
newshow = TVShow.new(obj['name'], obj['id'])
shows.insert(:show_id => newshow.id, :name => newshow.name)
Database.add_episodes(dataset2, newshow)
puts "Added show #{show_name}" unless !verbose
$logger.debug "...completed"
end
rescue => e
$logger.error("Exception in add_show trying to add <#{show_name}> : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]" unless !verbose
end
# Add episodes to the database. Receives a TVShow and the dataset episodes as parameters
# PRIVATE?
# SLOW METHOD?
#
def Database.add_episodes (dataset, show)
id = show.id
show.episodes.each do |i|
if dataset.where(:ep_id => i.id).count == 1
$logger.warn "The episode <#{i.title}> is already in the database"
else
dataset.insert(:ep_id => i.id, :title => i.title, :season_number => i.season, :episode_number => i.number, :airdate => i.airdate, :watched => false, :show_id => id)
$logger.debug "Added episode <#{i.title}>"
end
end
rescue => e
$logger.error("Exception in add_episodes : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Add only the new episodes to the database. Receives a TVShow and the dataset episodes as parameters
# PRIVATE=
# SLOW METHOD?
def Database.add_new_episodes (dataset, show, last_episode_s, last_episode_n)
id = show.id
episodes = show.episodes
if episodes.empty?
return
end
# Quick check if there are new episodes
if episodes[-1].season > last_episode_s
elsif last_episode_s == episodes[-1].season && episodes[-1].number > last_episode_n
else
$logger.info "No new episodes to add to <#{show.name}>"
return
end
# New episodes to add, full iteration:
episodes.each do |i|
if i.season > last_episode_s
dataset.insert(:ep_id => i.id, :title => i.title, :season_number => i.season, :episode_number => i.number, :airdate => i.airdate, :watched => false, :show_id => id)
$logger.debug "Added episode <#{i.title}>"
elsif last_episode_s == i.season && i.number > last_episode_n
dataset.insert(:ep_id => i.id, :title => i.title, :season_number => i.season, :episode_number => i.number, :airdate => i.airdate, :watched => false, :show_id => id)
$logger.debug "Added episode <#{i.title}>"
end
end
rescue => e
puts "Error: #{e.message} [#{e.class.to_s}]"
$logger.error("Exception in add_new_episodes trying to add episodes for <#{show.name}> : #{e.message} [#{e.class.to_s}]")
end
# Removes an episodes from the database.
# PRIVATE?
def Database.remove_episode (dataset, id)
if dataset.where(:ep_id => id).count == 1
dataset.where(:ep_id => id).delete
$logger.debug "Deleting episode with id <#{id.to_s}> from dataset "
else
$logger.warn "Couldn't delete episode with id <#{id.to_s}>. Entry not found."
end
rescue => e
puts "Error: #{e.message} [#{e.class.to_s}]"
$logger.error("Exception in remove_episode trying to remove item <#{id.to_s}> : #{e.message} [#{e.class.to_s}]")
end
# Removes a TVShow and all its episodes
# SLOW METHOD
def Database.remove_show(shows, dataset2, show_id)
if shows.where(:show_id => show_id).count == 1
shows.where(:show_id => show_id).delete
$logger.debug "Deleting show with id <#{show_id.to_s}> from dataset "
else
$logger.warn "Couldn't delete show with id <#{show_id.to_s}>. Entry not found."
end
# Remove episodes of that show
#dataset2.where(:show_id => show_id).each do |i|
# Database.remove_episode(dataset2, i[:ep_id])
#end
rescue => e
$logger.error("Exception in remove_show trying to remove show <#{show_id}> : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Performs all the updates to the DB
# SLOW METHOD?
def Database.update(shows, dataset2)
# scan database for watched=true
# once found one, check if the count of episodes where show_id is the same as the watched is higher than 1
# if it is higher, delete watched=true episode
dataset2.where(:watched => true).each do |i|
if dataset2.where(:show_id => i[:show_id]).count > 1
Database.remove_episode(dataset2, i[:ep_id])
else
$logger.info "The episode id <#{i[:ep_id].to_s}> wasn't deleted because it's the last one."
end
end
# Storing the "update" and only calling add_episodes when the update field changes would make this much faster
# Adds the new episodes of every tvshow checking the last season and episode numbers stored in the DB
shows.each do |i|
show = TVShow.new(i[:name], i[:show_id])
last_episode = dataset2.where(:show_id => i[:show_id]).order(:season_number, :episode_number).last
if (last_episode)
lasteps = last_episode[:season_number]
lastepn = last_episode[:episode_number]
else # Show without episodes stored
lasteps = 0
lastepn = 0
end
Database.add_new_episodes(dataset2, show, lasteps, lastepn)
end
rescue => e
$logger.error("Exception in update : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Returns the ID of a show stored in the database. Receives a string with the show name
# Mechanize::ResponseCodeError if show isn't found
def Database.get_show_id(dataset, showname)
show = dataset.where(:name => showname).to_a[0]
if show # Found in the database
show[:show_id]
else # Search online
$logger.warn("Show wasn't found in the database. Searching online.")
Web.get_show_id(showname)
end
rescue => e
$logger.error("Exception in get_show_id trying to get the id for <#{showname}> : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# NoMethodError when the episode id isn't found
def Database.get_episode_id(shows, dataset2, season, episode, show)
show_id = Database.get_show_id(shows, show)
dataset2.where(:show_id => show_id, :season_number => season, :episode_number => episode).to_a[0][:ep_id]
rescue => e
$logger.error("Exception in get_episode_id trying to get <#{show}>'s S#{season}E#{episode} id : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
def Database.set_watched(dataset, episodeid)
dataset.where(:ep_id => episodeid).update(:watched => true)
rescue => e
$logger.error("Exception in set_watched trying to set episode <#{episodeid}> as watched : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Returns a TVShow object. Receives the my_shows dataset and the show id
def Database.get_show (shows, id)
tvshowdata = shows.where(:show_id => id).to_a
TVShow.new(tvshowdata[0][:name], tvshowdata[0][:show_id])
rescue => e
$logger.error("Exception in get_show trying to get id <#{id}> : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Returns the episodes of a specific show id. Receives the episodes dataset and a show_id as parameters
def Database.get_episodes(dataset, show_id)
dataset.where(:show_id => show_id)
rescue => e
$logger.error("Exception in get_episodes trying to get episodes for show <#{show_id}> : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Returns the current number of entries in the given dataset
def Database.number_of_entries (dataset)
dataset.count
rescue => e
$logger.error("Exception in number_of_entries : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Sets all the episodes of a tv show as watched
# SLOW METHOD?
def Database.set_show_watched(shows, dataset2, show_id)
dataset2.where(:show_id => show_id).to_a.each do |i|
Database.set_watched(dataset2, i[:ep_id])
end
rescue => e
$logger.error("Exception in set_show_watched with show <#{show_id}> : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Returns an array of non-watched episodes, one per show.
def Database.next_episodes(shows, dataset2)
next_episodes = Array.new
shows.each do |i|
episode = dataset2.where(:show_id => i[:show_id], :watched => false).order(:airdate).to_a[0]
if episode != nil
next_episodes << episode
end
end
return next_episodes
rescue => e
$logger.error("Exception in next_episodes : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
def Database.contains(show, show_id)
shows.where(:show_id => show_id).count == 1
rescue => e
$logger.error("Exception in contains : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
def Database.clear(shows, dataset2)
shows.delete
dataset2.delete
rescue => e
$logger.error("Exception in clear : #{e.message} [#{e.class.to_s}]")
puts "Error: #{e.message} [#{e.class.to_s}]"
end
# Prints general information about the shows in the DB. Receives my_shows and episodes as parameters
# SLOW METHOD?
def Database.print_shows(shows, dataset2)
shows.order(:name).each do |i|
puts "TV Show <#{i[:name]}> (id #{i[:show_id].to_s}) - #{dataset2.where(:show_id => i[:show_id]).count.to_s} episodes stored"
end
puts
end
# Prints information about every show and episode stored in a readable format. Receives my_shows and episodes as parameters
def Database.print_full(shows, dataset2)
shows.order(:name).each do |show|
puts "TV Show <#{show[:name]}> (id #{show[:show_id].to_s})"
dataset2.where(:show_id => show[:show_id]).each do |ep|
season_number = ep[:season_number]<10 ? "0" + ep[:season_number].to_s : ep[:season_number].to_s
episode_number = ep[:episode_number]<10 ? "0" + ep[:episode_number].to_s : ep[:episode_number].to_s
watch = ep[:watched]? "watched" : "not watched"
puts "\tS#{season_number}E#{episode_number} - #{ep[:title].to_s} - #{watch}"
end
end
puts
end
end
end