http://code.google.com/p/dlibdb/source/detail?r=65
Added:
/trunk/dlibdb/app/models/thetvdb_query.rb
/trunk/dlibdb/app/models/thetvdb_show.rb
/trunk/dlibdb/app/models/thetvdb_update.rb
/trunk/dlibdb/db/migrate/20090923001319_convert_to_tvdb.rb
Deleted:
/trunk/dlibdb/app/models/tvrage_query.rb
/trunk/dlibdb/app/models/tvrage_show.rb
/trunk/dlibdb/app/models/tvrage_update.rb
Modified:
/trunk/dlibdb/app/controllers/search_controller.rb
/trunk/dlibdb/app/controllers/shows_controller.rb
/trunk/dlibdb/app/models/episode.rb
/trunk/dlibdb/app/models/season.rb
/trunk/dlibdb/app/models/show.rb
/trunk/dlibdb/app/views/episodes/_upcoming_table.html.erb
/trunk/dlibdb/app/views/search/_search.html.erb
/trunk/dlibdb/app/views/search/index.html.erb
/trunk/dlibdb/app/views/search/pick_show.html.erb
/trunk/dlibdb/app/views/shows/_show_episodes_table.html.erb
/trunk/dlibdb/config/environment.rb
=======================================
--- /dev/null
+++ /trunk/dlibdb/app/models/thetvdb_query.rb Thu Sep 24 15:04:59 2009
@@ -0,0 +1,27 @@
+class ThetvdbQuery
+ attr_accessor :query
+ attr_accessor :results
+
+ def initialize(query)
+ @query = query
+ @results = []
+ find_shows
+ end
+
+ private
+ def get_search_xml
+ url = "http://www.thetvdb.com/api/GetSeries.php?seriesname=" + \
+ CGI.escape(@query)
+ xml_data = Net::HTTP.get_response(URI.parse(url)).body
+ return REXML::Document.new(xml_data)
+ end
+
+ def find_shows
+ doc = get_search_xml
+ doc.elements.each("//Series") do |element|
+ # TODO: support more than english
+ next unless element.elements["language"].text.to_s == "en"
+ @results << ThetvdbShow.new(element)
+ end
+ end
+end
=======================================
--- /dev/null
+++ /trunk/dlibdb/app/models/thetvdb_show.rb Thu Sep 24 15:04:59 2009
@@ -0,0 +1,28 @@
+class ThetvdbShow
+ attr_accessor :seriesid
+ attr_accessor :name
+ attr_accessor :overview
+ attr_accessor :firstaired
+ attr_accessor :imdb_link
+
+ def initialize(element)
+ @seriesid = element.elements["seriesid"].text
+ @name = element.elements["SeriesName"].text
+ @overview = element.elements["Overview"].text rescue ""
+ @firstaired = element.elements["FirstAired"].text rescue ""
+ if element.elements["IMDB_ID"]
+ @imdb_link = "http://www.imdb.com/title/" + \
+ element.elements["IMDB_ID"].text
+ else
+ @imdb_link = nil
+ end
+ end
+
+ def duplicate?
+ return Episode.find_by_tvrage_showid(@showid) != nil
+ end
+
+ def active_duplicate?
+ return Episode.find_by_tvrage_showid_and_subscribed(@showid, true) !=
nil
+ end
+end
=======================================
--- /dev/null
+++ /trunk/dlibdb/app/models/thetvdb_update.rb Thu Sep 24 15:04:59 2009
@@ -0,0 +1,105 @@
+# This model is here to handle updating models from TheTVDB
+class ThetvdbUpdate
+ MIRROR_XML = 1
+ MIRROR_BANNER = 2
+ MIRROR_ZIP = 4
+
+ def self.get_mirrors
+ mirror_url = "http://www.thetvdb.com/api/#{$TVDB_API_KEY}/mirrors.xml"
+ mirror_list = {"xml" => [], "banner" => [], "zip" => []}
+ mirror_xml = Net::HTTP.get_response(URI.parse(mirror_url)).body
+ doc = REXML::Document.new(mirror_xml)
+ doc.elements.each("//Mirror") do |mirror|
+ typemask = mirror.elements["typemask"].text.to_i
+ path = mirror.elements["mirrorpath"].text
+ mirror_list["xml"] << path if typemask | MIRROR_XML == typemask
+ mirror_list["banner"] << path if typemask | MIRROR_BANNER == typemask
+ mirror_list["zip"] << path if typemask | MIRROR_ZIP == typemask
+ end
+
+ mirrors = {}
+ mirror_list.each do |name, list|
+ if list.length == 0
+ raise "TheTVDB: can't find any mirrors for #{name} files"
+ end
+ mirrors[name] = list.sort_by { rand }.first
+ end
+
+ return mirrors
+ end
+
+ def self.get_time
+ time_url = "http://www.thetvdb.com/api/Updates.php?type=none"
+ time_xml = Net::HTTP.get_response(URI.parse(time_url)).body
+ doc = REXML::Document.new(time_xml)
+ return doc.root.elements["Time"].text.to_i
+ end
+
+ def self.import_full_show_info(seriesid)
+ mirrors = get_mirrors
+
+ # TODO: support more languages than "en"
+ zip_url = "#{mirrors["zip"]}/api/#{$TVDB_API_KEY}/series/" \
+ "#{seriesid}/all/en.zip"
+ zip_data = Net::HTTP.get_response(URI.parse(zip_url)).body
+ zip_path = Tempfile.new("zip")
+ zip_path.write(zip_data)
+ zip_path.close
+ show_doc = nil
+ banner_doc = nil
+ Zip::ZipFile.open(zip_path.path) do |zip|
+ show_doc = REXML::Document.new(zip.file.read("en.xml"))
+ banner_doc = REXML::Document.new(zip.file.read("banners.xml"))
+ end
+ zip_path.unlink
+
+ show = Show.find_or_create_by_seriesid(seriesid)
+ show.seriesid = seriesid
+ update_show_from_xml(show, show_doc)
+ update_episodes_from_xml(show, show_doc)
+
+ return show.id
+ end
+
+ def self.update_show_from_xml(show, doc)
+ show.subscribed = true
+ show_element = doc.root.elements["Series"]
+ show.name = show_element.elements["SeriesName"].text
+ show.summary = show_element.elements["Overview"].text rescue ""
+ show.start_date = show_element.elements["FirstAired"].text
+ show.runtime = show_element.elements["Runtime"].text rescue 60
+ if show_element.elements["Airs_Time"].text
+ pm_adjust = show_element.elements["Airs_Time"].text[/ PM/] ? 12 : 0
+ show.airhour, show.airminute = \
+ show_element.elements["Airs_Time"].text[/^\d+:\d+/].split(":")
+ show.airhour += pm_adjust
+ else
+ show.airhour = 0
+ show.airminute = 0
+ end
+ show.runtime = show_element.elements["Runtime"].text
+ show.preferred_formats ||=
Preferences.get_preference("preferred_formats")
+ show.last_updated = self.get_time
+ if doc.root.elements["IMDB_ID"]
+ show.imdb_link = "http://www.idmb.com/title/" + \
+ doc.root.elements["IMDB_ID"].text
+ end
+ show.save!
+ end
+
+ def self.update_episodes_from_xml(show, doc)
+ doc.elements.each("//Episode") do |e|
+ next unless e.elements["FirstAired"].text # skip episodes w/no air
date
+ season = Season.find_or_create_by_show_id_and_season_number(show.id,
+ e.elements["SeasonNumber"].text.to_i)
+ season.save!
+ episode = \
+ Episode.find_or_create_by_season_id_and_episode_number(season.id,
+ e.elements["EpisodeNumber"].text.to_i)
+ episode.title = e.elements["EpisodeName"].text
+ episode.summary = e.elements["Overview"].text
+ episode.airdate = e.elements["FirstAired"].text
+ episode.save!
+ end
+ end
+end
=======================================
--- /dev/null
+++ /trunk/dlibdb/db/migrate/20090923001319_convert_to_tvdb.rb Thu Sep 24
15:04:59 2009
@@ -0,0 +1,17 @@
+class ConvertToTvdb < ActiveRecord::Migration
+ def self.up
+ # shows
+ add_column :shows, :seriesid, :string
+ add_column :shows, :imdb_link, :string
+ add_column :shows, :thetvdb_link, :string
+ add_column :shows, :last_updated, :integer
+ remove_column :shows, :tvrage_showid
+ remove_column :shows, :tvrage_showlink
+
+ # videos
+ remove_column :videos, :tvrage_link
+ end
+
+ def self.down
+ end
+end
=======================================
--- /trunk/dlibdb/app/models/tvrage_query.rb Mon Sep 21 01:09:40 2009
+++ /dev/null
@@ -1,28 +0,0 @@
-# This model is just to provide helper methods that query TVrage and
-# return an xml document
-class TvrageQuery
- attr_accessor :query
- attr_accessor :results
-
- def initialize(query)
- @query = query
- @results = []
- find_shows
- end
-
- private
- def get_search_xml
- url = "http://services.tvrage.com/feeds/search.php?show=" + \
- CGI.escape(@query)
- puts url
- xml_data = Net::HTTP.get_response(URI.parse(url)).body
- return REXML::Document.new(xml_data)
- end
-
- def find_shows
- doc = get_search_xml
- doc.elements.each("//show") do |element|
- @results << TvrageShow.new(element)
- end
- end
-end
=======================================
--- /trunk/dlibdb/app/models/tvrage_show.rb Mon Sep 21 01:09:40 2009
+++ /dev/null
@@ -1,22 +0,0 @@
-# Represent show's info from TVRage
-class TvrageShow
- attr_accessor :showid
- attr_accessor :name
- attr_accessor :link
- attr_accessor :seasons
-
- def initialize(element)
- @showid = element.elements["showid"].text
- @name = element.elements["name"].text
- @link = element.elements["link"].text
- @seasons = element.elements["seasons"].text
- end
-
- def duplicate?
- return Episode.find_by_tvrage_showid(@showid) != nil
- end
-
- def active_duplicate?
- return Episode.find_by_tvrage_showid_and_subscribed(@showid, true) !=
nil
- end
-end
=======================================
--- /trunk/dlibdb/app/models/tvrage_update.rb Mon Sep 21 20:28:44 2009
+++ /dev/null
@@ -1,49 +0,0 @@
-# This model is here to handle updating models from tvrage
-class TvrageUpdate
- def self.update_full_show_info(showid)
- doc = TvrageUpdate.get_show_xml(showid)
- show = \
-
Show.find_or_create_by_tvrage_showid(doc.root.elements["showid"].text)
- show.name = doc.root.elements["name"].text
- show.tvrage_showlink = doc.root.elements["showlink"].text
- show.start_date = doc.root.elements["started"].text
- show.end_date = doc.root.elements["ended"].text
- show.runtime = doc.root.elements["runtime"].text
- show.airhour, show.airminute = doc.root.elements["airtime"] \
- .text[/^\d+:\d+/].split(":")
- show.subscribed = true
- if ! show.preferred_formats or show.preferred_formats.length == 0
- show.preferred_formats ||=
Preferences.get_preference("preferred_formats")
- end
- show.save!
-
- # Create or Update Seasons and Episodes
- doc.elements.each("Show/Episodelist/Season") do |s|
- season = Season.find_or_create_by_show_and_season_number(show,
-
s.attributes["no"])
- season.save!
-
- # Episodes now
- s.elements.each("episode") do |e|
- episode = Episode.find_or_create_by_season_and_episode_number(
- season, e.elements["seasonnum"].text)
- next unless episode
- # TODO: what's the valid parse function to turn " into "?
- episode.title = e.elements["title"].text.gsub(""","'")
- next unless episode.title
- episode.airdate = e.elements["airdate"].text
- next unless episode.airdate
- episode.tvrage_link = e.elements["link"].text
- episode.save!
- end
- end
-
- return show.id
- end
-
- def self.get_show_xml(showid)
- url
= "http://services.tvrage.com/feeds/full_show_info.php?sid=#{showid}"
- xml_data = Net::HTTP.get_response(URI.parse(url)).body
- return REXML::Document.new(xml_data)
- end
-end
=======================================
--- /trunk/dlibdb/app/controllers/search_controller.rb Mon Sep 21 01:09:40
2009
+++ /trunk/dlibdb/app/controllers/search_controller.rb Thu Sep 24 15:04:59
2009
@@ -7,6 +7,6 @@
def pick_show
@show_name = params[:show_name]
- @results = TvrageQuery.new(@show_name).results
+ @results = ThetvdbQuery.new(@show_name).results
end
end
=======================================
--- /trunk/dlibdb/app/controllers/shows_controller.rb Wed Sep 23 16:36:37
2009
+++ /trunk/dlibdb/app/controllers/shows_controller.rb Thu Sep 24 15:04:59
2009
@@ -54,9 +54,8 @@
end
def add_show
- tvrage_showid = params[:id]
- show_id = TvrageUpdate.update_full_show_info(tvrage_showid)
- flash[:notice] = "Show successfully imported from TVRage."
+ show_id = ThetvdbUpdate.import_full_show_info(params[:id])
+ flash[:notice] = "Show successfully imported from TheTVDB."
redirect_to :action => :edit, :id => show_id
end
=======================================
--- /trunk/dlibdb/app/models/episode.rb Tue Sep 22 15:08:27 2009
+++ /trunk/dlibdb/app/models/episode.rb Thu Sep 24 15:04:59 2009
@@ -1,6 +1,8 @@
class Episode < Video
belongs_to :season
+ validates_presence_of :airdate
+
def epnumberstring
return "e" + episode_number.to_s.rjust(2, '0')
end
=======================================
--- /trunk/dlibdb/app/models/season.rb Wed Sep 23 13:34:15 2009
+++ /trunk/dlibdb/app/models/season.rb Thu Sep 24 15:04:59 2009
@@ -3,6 +3,9 @@
belongs_to :show
has_many :episodes, :dependent => :destroy
+ validates_presence_of :show_id, :season_number
+ validates_uniqueness_of :season_number, :scope => :show_id
+
def to_s
return "s" + season_number.to_s.rjust(2,'0')
end
@@ -11,16 +14,6 @@
return show.filename + "." + to_s
end
- def self.find_or_create_by_show_and_season_number(show, num)
- s = show.seasons.select { |season| season.season_number == num.to_i
}.first
- unless s
- s = Season.new()
- s.show = show
- s.season_number = num
- end
- return s
- end
-
def <=>(b)
return season_number <=> b.season_number
end
=======================================
--- /trunk/dlibdb/app/models/show.rb Wed Sep 23 18:41:52 2009
+++ /trunk/dlibdb/app/models/show.rb Thu Sep 24 15:04:59 2009
@@ -3,6 +3,9 @@
has_many :seasons, :dependent => :destroy
has_many :episodes, :through => :seasons
+ validates_presence_of :runtime
+ validates_uniqueness_of :seriesid
+
def to_s
return name
end
@@ -43,7 +46,7 @@
episodes.each do |e|
next if e.recordings.length > 0
- next if e.airdate >= today
+ next if e.airdate and e.airdate >= today
next if e.need_fetch
res << e
end
=======================================
--- /trunk/dlibdb/app/views/episodes/_upcoming_table.html.erb Wed Sep 23
22:35:12 2009
+++ /trunk/dlibdb/app/views/episodes/_upcoming_table.html.erb Thu Sep 24
15:04:59 2009
@@ -46,7 +46,7 @@
<td><%=h episode.season.show %></td>
<td><%=h episode.title %></td>
<td><%= link_to "Show Episode", "/episodes/"+episode.id %></td>
- <td><%= link_to 'TVRage', episode.tvrage_link %></td>
+ <td></td>
</tr>
<% end -%>
</table>
=======================================
--- /trunk/dlibdb/app/views/search/_search.html.erb Mon Sep 21 01:09:40 2009
+++ /trunk/dlibdb/app/views/search/_search.html.erb Thu Sep 24 15:04:59 2009
@@ -1,4 +1,4 @@
<% form_tag '/search/pick_show', :method => :put do -%>
Show name: <%= text_field_tag :show_name, @show_name %></br>
- <%= submit_tag "Search TVRage" %>
+ <%= submit_tag "Search TheTVDB" %>
<% end %>
=======================================
--- /trunk/dlibdb/app/views/search/index.html.erb Tue Sep 22 23:09:48 2009
+++ /trunk/dlibdb/app/views/search/index.html.erb Thu Sep 24 15:04:59 2009
@@ -2,7 +2,7 @@
<p>Enter your search your term in the field below, you can search various
databases for your shows by selecting their tab.</p>
<div class="tabs">
<ul>
- <li><a href="#tvrage">TVRage Show Search</a></li>
+ <li><a href="#tvrage">TheTVDB Show Search</a></li>
<li><a href="#imdb">IMDB Movie Search</a></li>
</ul>
<div id="tvrage">
=======================================
--- /trunk/dlibdb/app/views/search/pick_show.html.erb Tue Sep 22 23:09:48
2009
+++ /trunk/dlibdb/app/views/search/pick_show.html.erb Thu Sep 24 15:04:59
2009
@@ -1,9 +1,9 @@
-<h1 class="myriad">TVRage search results for <%=h @show_name %></h1>
+<h1 class="myriad">TheTVDB search results for <%=h @show_name %></h1>
<table class="result-table" cellspacing="0">
<thead>
<tr>
<th class="aleft ui-widget-header">Show Name</th>
- <th class="acenter ui-widget-header">Seasons</th>
+ <th class="acenter ui-widget-header">Overview</th>
<th class="acenter ui-widget-header">More Details</th>
</tr>
</thead>
@@ -21,9 +21,9 @@
cls = (cls == "") ? "alt" : ""
%>
<tr class="<%=cls%>">
- <td class="aleft"><%= link_to show.name, {:controller
=> :shows, :action => :add_show, :id => show.showid} %></td>
- <td class="acenter"><% txt = (show.seasons.to_i ==
1) ? "season" : "seasons" %><%= show.seasons %> <%=txt %></td>
- <td class="acenter"><%= link_to "more details", show.link %></td>
+ <td class="aleft"><%= link_to show.name, {:controller
=> :shows, :action => :add_show, :id => show.seriesid} %></td>
+ <td class="acenter"><%=h show.overview %></td>
+ <td class="acenter"><%= show.imdb_link ? link_to("IMDB",
show.imdb_link) : "" %></td>
</tr>
<% end -%>
<% end -%>
=======================================
--- /trunk/dlibdb/app/views/shows/_show_episodes_table.html.erb Wed Sep 23
16:36:37 2009
+++ /trunk/dlibdb/app/views/shows/_show_episodes_table.html.erb Thu Sep 24
15:04:59 2009
@@ -21,7 +21,6 @@
<td class="acenter"><%=h episode.episode_number %></td>
<td class="aleft"><%=h episode.title %></td>
<td class="acenter<%=airclass%>"><%=h airdate %></td>
- <td class="acenter"><%= link_to 'TVRage', episode.tvrage_link, :target
=> '_blank' %> ·
<%= link_to 'Show', episode %> ·
<%= link_to 'Destroy', episode, :confirm => 'Are you sure?', :method
=> :delete %></td>
</tr>
=======================================
--- /trunk/dlibdb/config/environment.rb Wed Sep 23 11:41:33 2009
+++ /trunk/dlibdb/config/environment.rb Thu Sep 24 15:04:59 2009
@@ -47,7 +47,9 @@
require 'net/http'
require 'rexml/document'
require 'rss'
+require 'tempfile'
require 'tzinfo'
+require 'zip/zipfilesystem'
$DLIBDB_VERSION = '0.2'
$TVDB_API_KEY = "DA3D6CF76DAA8D33"