etvnet_seek 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +5 -1
- data/Rakefile +45 -0
- data/bin/etvnet_seek +8 -15
- data/etvnet_seek.gemspec +10 -5
- data/lib/etvnet_seek/commander.rb +93 -0
- data/lib/{cookie_helper.rb → etvnet_seek/cookie_helper.rb} +21 -32
- data/lib/etvnet_seek/core/access_page.rb +18 -0
- data/lib/etvnet_seek/core/announces_page.rb +34 -0
- data/lib/etvnet_seek/core/base_page.rb +129 -0
- data/lib/etvnet_seek/core/browse_media_item.rb +40 -0
- data/lib/etvnet_seek/core/channel_media_item.rb +13 -0
- data/lib/etvnet_seek/core/channels_page.rb +37 -0
- data/lib/etvnet_seek/core/freetv_page.rb +38 -0
- data/lib/etvnet_seek/core/group_media_item.rb +14 -0
- data/lib/etvnet_seek/core/group_page.rb +45 -0
- data/lib/etvnet_seek/core/login_page.rb +46 -0
- data/lib/etvnet_seek/core/main_page.rb +20 -0
- data/lib/etvnet_seek/core/media_info.rb +31 -0
- data/lib/etvnet_seek/core/media_item.rb +45 -0
- data/lib/etvnet_seek/core/media_page.rb +43 -0
- data/lib/etvnet_seek/core/page.rb +19 -0
- data/lib/etvnet_seek/core/page_factory.rb +52 -0
- data/lib/etvnet_seek/core/search_page.rb +7 -0
- data/lib/etvnet_seek/core/service_call.rb +32 -0
- data/lib/etvnet_seek/link_info.rb +33 -0
- data/lib/etvnet_seek/main.rb +177 -0
- data/lib/etvnet_seek/user_selection.rb +45 -0
- data/lib/runglish.rb +115 -117
- data/spec/etvnet_seek_spec.rb +7 -13
- metadata +76 -6
- data/lib/main.rb +0 -95
- data/lib/url_seeker.rb +0 -97
data/CHANGES
CHANGED
data/Rakefile
CHANGED
@@ -5,6 +5,44 @@ rescue LoadError
|
|
5
5
|
exit
|
6
6
|
end
|
7
7
|
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'metric_fu'
|
11
|
+
|
12
|
+
MetricFu::Configuration.run do |config|
|
13
|
+
#define which metrics you want to use
|
14
|
+
config.metrics = [:churn, :saikuro, :flog, :flay, :reek, :roodi, :rcov]
|
15
|
+
config.graphs = [:flog, :flay, :reek, :roodi, :rcov]
|
16
|
+
config.flay = { :dirs_to_flay => ['app', 'lib'],
|
17
|
+
:minimum_score => 100 }
|
18
|
+
config.flog = { :dirs_to_flog => ['app', 'lib'] }
|
19
|
+
config.reek = { :dirs_to_reek => ['app', 'lib'] }
|
20
|
+
config.roodi = { :dirs_to_roodi => ['app', 'lib'] }
|
21
|
+
config.saikuro = { :output_directory => 'scratch_directory/saikuro',
|
22
|
+
:input_directory => ['app', 'lib'],
|
23
|
+
:cyclo => "",
|
24
|
+
:filter_cyclo => "0",
|
25
|
+
:warn_cyclo => "5",
|
26
|
+
:error_cyclo => "7",
|
27
|
+
:formater => "text"} #this needs to be set to "text"
|
28
|
+
config.churn = { :start_date => "1 year ago", :minimum_churn_count => 10}
|
29
|
+
config.rcov = { :environment => 'test',
|
30
|
+
:test_files => ['test/**/*_test.rb',
|
31
|
+
'spec/**/*_spec.rb'],
|
32
|
+
:rcov_opts => ["--sort coverage",
|
33
|
+
"--no-html",
|
34
|
+
"--text-coverage",
|
35
|
+
"--no-color",
|
36
|
+
"--profile",
|
37
|
+
"--rails",
|
38
|
+
"--exclude /gems/,/Library/,spec"]}
|
39
|
+
config.graph_engine = :bluff
|
40
|
+
end
|
41
|
+
rescue LoadError
|
42
|
+
puts "MetricFu is not available. Install it with: sudo gem install metric_fu"
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
8
46
|
task :zip do
|
9
47
|
zip :archive => "etvnet_seek.zip", :dir => "."
|
10
48
|
end
|
@@ -15,4 +53,11 @@ task :"run:gem" do
|
|
15
53
|
puts ruby("#{command}")
|
16
54
|
end
|
17
55
|
|
56
|
+
# configure rspec
|
57
|
+
#Spec::Rake::SpecTask.new do |spec|
|
58
|
+
# spec.spec_files = FileList["spec/**/*_spec.rb"]
|
59
|
+
# spec.spec_opts << "--color"
|
60
|
+
# spec.libs += ["lib", "spec"]
|
61
|
+
#end
|
62
|
+
|
18
63
|
task :default => :zip
|
data/bin/etvnet_seek
CHANGED
@@ -7,26 +7,19 @@ $:.unshift(File::join(File::dirname(File::dirname(__FILE__)), "lib"))
|
|
7
7
|
|
8
8
|
$KCODE='u'
|
9
9
|
|
10
|
-
require 'main'
|
10
|
+
require 'etvnet_seek/main'
|
11
11
|
|
12
|
-
|
12
|
+
trap('INT') { puts "Program was interrupted..."; exit }
|
13
13
|
|
14
|
-
|
14
|
+
client = Main.new
|
15
15
|
|
16
|
-
|
17
|
-
keywords = Runglish.new.lat_to_ru(keywords)
|
18
|
-
end
|
16
|
+
link_info = client.seek ARGV.join(' ')
|
19
17
|
|
20
|
-
|
18
|
+
if not link_info.nil? and link_info.resolved?
|
19
|
+
puts "Link #{link_info.text} [#{link_info.name} (#{link_info.media_file})]: #{link_info.link}"
|
21
20
|
|
22
|
-
|
23
|
-
puts "Link: #{movie_link}"
|
24
|
-
|
25
|
-
if RUBY_PLATFORM =~ /(win|w)32$/
|
26
|
-
`start wmplayer #{movie_link}`
|
27
|
-
elsif RUBY_PLATFORM =~ /darwin/
|
28
|
-
`open #{movie_link}`
|
29
|
-
end
|
21
|
+
launch = ask("Launch link (y/n)?")
|
30
22
|
|
23
|
+
client.launch_link link_info.link unless launch =~ /n/i
|
31
24
|
end
|
32
25
|
|
data/etvnet_seek.gemspec
CHANGED
@@ -4,7 +4,7 @@ require "rake"
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{etvnet_seek}
|
7
|
-
s.version = "0.
|
7
|
+
s.version = "0.4.0"
|
8
8
|
|
9
9
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
10
10
|
|
@@ -34,8 +34,13 @@ Gem::Specification.new do |s|
|
|
34
34
|
|
35
35
|
s.add_dependency("json_pure", ">= 1.2.0")
|
36
36
|
s.add_dependency("highline", ">= 1.5.1")
|
37
|
-
s.add_dependency("
|
38
|
-
|
39
|
-
|
40
|
-
s.add_development_dependency "
|
37
|
+
s.add_dependency("libxml-ruby", ">= 1.1.3")
|
38
|
+
s.add_dependency("nokogiri", ">= 1.4.1")
|
39
|
+
|
40
|
+
s.add_development_dependency "rspec", ">= 1.2.9"
|
41
|
+
s.add_development_dependency "mocha", ">= 0.9.7"
|
42
|
+
s.add_development_dependency "metric_fu"
|
43
|
+
s.add_development_dependency "reek"
|
44
|
+
s.add_development_dependency "roodi"
|
45
|
+
s.add_development_dependency "googlecharts"
|
41
46
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class Commander
|
2
|
+
attr_accessor :mode
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@options = parse_options
|
6
|
+
end
|
7
|
+
|
8
|
+
def search_mode?
|
9
|
+
@options[:runglish]
|
10
|
+
end
|
11
|
+
|
12
|
+
def runglish_mode?
|
13
|
+
@options[:runglish]
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_initial_mode
|
17
|
+
if @options[:search] == true
|
18
|
+
'search'
|
19
|
+
elsif @options[:best_ten] == true
|
20
|
+
'best_ten'
|
21
|
+
elsif @options[:popular] == true
|
22
|
+
'popular'
|
23
|
+
elsif @options[:we_recommend] == true
|
24
|
+
'we_recommend'
|
25
|
+
elsif @options[:channels] == true
|
26
|
+
'channels'
|
27
|
+
else
|
28
|
+
'main'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def parse_options
|
35
|
+
# This hash will hold all of the options
|
36
|
+
# parsed from the command-line by
|
37
|
+
# OptionParser.
|
38
|
+
options = {}
|
39
|
+
|
40
|
+
optparse = OptionParser.new do|opts|
|
41
|
+
# Set a banner, displayed at the top
|
42
|
+
# of the help screen.
|
43
|
+
opts.banner = "Usage: etvnet_seek [options] keywords"
|
44
|
+
|
45
|
+
options[:search] = false
|
46
|
+
opts.on( '-s', '--search', 'Display Search Menu' ) do
|
47
|
+
options[:search] = true
|
48
|
+
end
|
49
|
+
|
50
|
+
options[:runglish] = false
|
51
|
+
opts.on( '-r', '--runglish', 'Enter russian keywords in translit' ) do
|
52
|
+
options[:runglish] = true
|
53
|
+
end
|
54
|
+
|
55
|
+
options[:best_ten] = false
|
56
|
+
opts.on( '-b', '--best-ten', 'Display Best 10 Menu' ) do
|
57
|
+
options[:best_ten] = true
|
58
|
+
end
|
59
|
+
|
60
|
+
options[:popular] = false
|
61
|
+
opts.on( '-p', '--popular', 'Display Popular Menu' ) do
|
62
|
+
options[:popular] = true
|
63
|
+
end
|
64
|
+
|
65
|
+
options[:we_recommend] = false
|
66
|
+
opts.on( '-w', '--we-recommend', 'Display We recommend Menu' ) do
|
67
|
+
options[:we_recommend] = true
|
68
|
+
end
|
69
|
+
|
70
|
+
options[:channels] = false
|
71
|
+
opts.on( '-c', '--channels', 'Display Channels Menu' ) do
|
72
|
+
options[:channels] = true
|
73
|
+
end
|
74
|
+
|
75
|
+
options[:main] = false
|
76
|
+
opts.on( '-m', '--main', 'Display Main Menu' ) do
|
77
|
+
options[:main] = true
|
78
|
+
end
|
79
|
+
|
80
|
+
# This displays the help screen, all programs are
|
81
|
+
# assumed to have this option.
|
82
|
+
opts.on( '-h', '--help', 'Display this screen' ) do
|
83
|
+
puts opts
|
84
|
+
exit
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
optparse.parse!
|
89
|
+
|
90
|
+
options
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -1,43 +1,25 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'uri'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
headers = { "Content-Type" => "application/x-www-form-urlencoded" }
|
10
|
-
resp, data = conn.post(uri.path,
|
11
|
-
"action=login&username=#{username}&pwd=#{password}&skip_notice=&redirect=", headers)
|
12
|
-
|
13
|
-
cookie = resp.response['set-cookie']
|
4
|
+
class CookieHelper
|
5
|
+
|
6
|
+
def initialize cookie_file_name
|
7
|
+
@cookie_file_name = cookie_file_name
|
8
|
+
end
|
14
9
|
|
15
|
-
|
10
|
+
def load_cookie
|
11
|
+
File.exist?(@cookie_file_name) ? read_cookie : nil
|
16
12
|
end
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
auth, expires = get_auth_and_expires(cookie)
|
22
|
-
username = get_username(cookie)
|
23
|
-
path = "/"
|
24
|
-
domain = ".etvnet.ca"
|
25
|
-
|
26
|
-
cookies_text = <<-TEXT
|
27
|
-
auth=#{auth}; expires=#{expires}; path=#{path}; domain=#{domain}
|
28
|
-
username=#{username}; expires=#{expires}; path=#{path}; domain=#{domain}
|
29
|
-
TEXT
|
30
|
-
|
31
|
-
new_cookie = ""
|
32
|
-
require 'stringio'
|
33
|
-
StringIO.new(cookies_text).each_line do |line|
|
34
|
-
new_cookie = new_cookie + line.strip + "; "
|
35
|
-
end
|
14
|
+
def save_cookie cookie
|
15
|
+
File.open(@cookie_file_name, 'w') { |file| file.puts cookie }
|
16
|
+
end
|
36
17
|
|
37
|
-
|
18
|
+
def delete_cookie
|
19
|
+
File.delete @cookie_file_name if File.exist? @cookie_file_name
|
38
20
|
end
|
39
21
|
|
40
|
-
def get_auth_and_expires cookie
|
22
|
+
def self.get_auth_and_expires cookie
|
41
23
|
length = "auth=".length
|
42
24
|
|
43
25
|
auth = ""
|
@@ -66,7 +48,7 @@ module CookieHelper
|
|
66
48
|
[auth, expires]
|
67
49
|
end
|
68
50
|
|
69
|
-
def get_username cookie
|
51
|
+
def self.get_username cookie
|
70
52
|
length = "username=".length
|
71
53
|
|
72
54
|
username = ""
|
@@ -90,4 +72,11 @@ module CookieHelper
|
|
90
72
|
|
91
73
|
username
|
92
74
|
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def read_cookie
|
79
|
+
File.open(@cookie_file_name, 'r') { |file| file.gets }
|
80
|
+
end
|
81
|
+
|
93
82
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class AccessPage < ServiceCall
|
2
|
+
ACCESS_URL = Page::BASE_URL + "/cgi-bin/video/access.fcgi"
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
super(ACCESS_URL)
|
6
|
+
end
|
7
|
+
|
8
|
+
def request_media_info media_file, cookie
|
9
|
+
params = { 'action' => 'start_video', 'bitrate' => '600',
|
10
|
+
'media_file'=> media_file, 'replay' => '1', 'skin' => 'JSON' }
|
11
|
+
headers = { 'Cookie' => cookie }
|
12
|
+
|
13
|
+
response = post(params, headers)
|
14
|
+
|
15
|
+
MediaInfo.new JSON.parse(response.body)["PARAMETERS"]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class AnnouncesPage < MediaPage
|
2
|
+
ANNOUNCES_URL = BASE_URL + "/announces.html"
|
3
|
+
|
4
|
+
def initialize()
|
5
|
+
super(ANNOUNCES_URL)
|
6
|
+
end
|
7
|
+
|
8
|
+
def category_breadcrumbs
|
9
|
+
[]
|
10
|
+
end
|
11
|
+
|
12
|
+
def items
|
13
|
+
list = []
|
14
|
+
|
15
|
+
document.css("table tr td div").each do |item|
|
16
|
+
unless item.css("a").at(0).nil?
|
17
|
+
image = item.css("img").at(0).attributes['src'].value.strip
|
18
|
+
|
19
|
+
unless image == 'images/banner_announces.jpg'
|
20
|
+
text = item.css("img").at(0).attributes['alt'].value.strip
|
21
|
+
href = item.css("a").at(0).attributes['href'].value
|
22
|
+
image = item.css("img").at(0).attributes['src'].value.strip
|
23
|
+
|
24
|
+
record = BrowseMediaItem.new(text, href)
|
25
|
+
record.image = image
|
26
|
+
|
27
|
+
list << record
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
list
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
class BasePage < Page
|
2
|
+
def items
|
3
|
+
list = []
|
4
|
+
|
5
|
+
document.css("#tblCategories a").each do |item|
|
6
|
+
text = item.css("img").at(0).attributes['alt'].value
|
7
|
+
href = item['href']
|
8
|
+
|
9
|
+
list << MediaItem.new(text, href)
|
10
|
+
end
|
11
|
+
|
12
|
+
list
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
document.css("title").text
|
17
|
+
end
|
18
|
+
|
19
|
+
def page_title
|
20
|
+
document.css(".global_content .global_content h1").text
|
21
|
+
end
|
22
|
+
|
23
|
+
def navigation_menu
|
24
|
+
list = []
|
25
|
+
|
26
|
+
document.css("table tr td .navigation").first.parent.parent.parent.css("tr td a").each do |item|
|
27
|
+
text = item.children.at(0).content
|
28
|
+
href = item['href']
|
29
|
+
|
30
|
+
list << MediaItem.new(text, href) unless href =~ /(login|signup)/
|
31
|
+
end
|
32
|
+
|
33
|
+
list
|
34
|
+
end
|
35
|
+
|
36
|
+
def category_breadcrumbs
|
37
|
+
list = []
|
38
|
+
|
39
|
+
document.css("table tr td table tr td table tr td strong").each_with_index do |item, index|
|
40
|
+
if index == 0
|
41
|
+
item.children.each do |child|
|
42
|
+
text = child.text
|
43
|
+
link = child.attributes['href']
|
44
|
+
href = link.nil? ? nil : link.value
|
45
|
+
|
46
|
+
list << MediaItem.new(text, href)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
list
|
52
|
+
end
|
53
|
+
|
54
|
+
def categories
|
55
|
+
list = []
|
56
|
+
|
57
|
+
document.css("table").each_with_index do |table1, index1|
|
58
|
+
if index1 == 5
|
59
|
+
table1.css("tr/td/table/tr/td/table").each_with_index do |table2, index2|
|
60
|
+
if index2 == 2
|
61
|
+
table2.css("tr[2]/td[2]/table").each_with_index do |table3, index3|
|
62
|
+
|
63
|
+
#if index2 > 1
|
64
|
+
table2.css("tr td a").each_with_index do |item2, index4|
|
65
|
+
link = item2.attributes['href'].value
|
66
|
+
|
67
|
+
if index4 > 0
|
68
|
+
text = item2.text
|
69
|
+
href = link
|
70
|
+
|
71
|
+
additional_info = additional_info(item2, 2)
|
72
|
+
|
73
|
+
list << MediaItem.new(text, href, additional_info)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
list
|
83
|
+
end
|
84
|
+
|
85
|
+
def title_items
|
86
|
+
list = []
|
87
|
+
|
88
|
+
root = nil
|
89
|
+
document.css("a").each do |item|
|
90
|
+
link = item.attributes['href']
|
91
|
+
|
92
|
+
unless link.value =~ /login.fcgi/
|
93
|
+
if link.value =~ /order_by/
|
94
|
+
root = link.parent.parent.parent.parent.parent.parent
|
95
|
+
break
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
if root
|
101
|
+
root.css("td").each do |item|
|
102
|
+
if item.search("table/tr/td/a").size > 0
|
103
|
+
link = item.css("table tr td a").first
|
104
|
+
|
105
|
+
text = link.text
|
106
|
+
href = link.attributes['href'].value
|
107
|
+
|
108
|
+
list << MediaItem.new(text, href)
|
109
|
+
elsif item.children.size == 1
|
110
|
+
if list.all? { |e| e.text != item.text }
|
111
|
+
list << MediaItem.new(item.text, nil)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
list
|
118
|
+
end
|
119
|
+
|
120
|
+
protected
|
121
|
+
|
122
|
+
def additional_info node, index
|
123
|
+
children = node.parent.children
|
124
|
+
if children.size > 0
|
125
|
+
element = children.at(index)
|
126
|
+
element.text if element
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class BrowseMediaItem < MediaItem
|
2
|
+
attr_accessor :folder, :showtime, :year, :duration, :rating_image, :image
|
3
|
+
|
4
|
+
def initialize(text, link)
|
5
|
+
super(text, link)
|
6
|
+
end
|
7
|
+
|
8
|
+
def folder?
|
9
|
+
folder == true
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
if folder?
|
14
|
+
buffer = "*** Folder *** "
|
15
|
+
else
|
16
|
+
buffer = ""
|
17
|
+
end
|
18
|
+
|
19
|
+
buffer += text
|
20
|
+
|
21
|
+
unless folder?
|
22
|
+
if underscore_name
|
23
|
+
buffer += ": #{underscore_name}"
|
24
|
+
else
|
25
|
+
buffer += ": #{link}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
buffer += " --- #{showtime}" if showtime
|
30
|
+
|
31
|
+
buffer += " (#{media_file})" if not media_file.nil? and media_file.size > 0
|
32
|
+
buffer += " --- #{year}" if not year.nil? and year.size > 2
|
33
|
+
buffer += " --- #{duration}" if not duration.nil? and duration.size > 0
|
34
|
+
buffer += " --- #{image}" if image
|
35
|
+
buffer += " --- #{rating_image}" if rating_image
|
36
|
+
|
37
|
+
buffer
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ChannelMediaItem < MediaItem
|
2
|
+
attr_reader :archive_link
|
3
|
+
|
4
|
+
def initialize(text, link, archive_link)
|
5
|
+
super(text, link)
|
6
|
+
|
7
|
+
@archive_link = archive_link
|
8
|
+
end
|
9
|
+
|
10
|
+
def channel
|
11
|
+
link[link.index("channel=") + "channel=".size, link.size-1]
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class ChannelsPage < MediaPage
|
2
|
+
BROWSE_URL = BASE_URL + "/cgi-bin/video/eitv_browse.fcgi"
|
3
|
+
CHANNELS_URL = BROWSE_URL + "?action=channels"
|
4
|
+
|
5
|
+
def initialize url = CHANNELS_URL
|
6
|
+
super(url)
|
7
|
+
end
|
8
|
+
|
9
|
+
def items
|
10
|
+
list = []
|
11
|
+
|
12
|
+
document.css("table table table.rounded_white table tr").each_with_index do |item, index|
|
13
|
+
links = item.css("table tr td a")
|
14
|
+
|
15
|
+
text = item.children.at(0).text.strip
|
16
|
+
|
17
|
+
if text.size > 0
|
18
|
+
link = nil
|
19
|
+
archive_link = nil
|
20
|
+
|
21
|
+
if links.size > 0
|
22
|
+
href = links[0]
|
23
|
+
archive_href = links[1]
|
24
|
+
|
25
|
+
link = href.attributes['href'].value unless href.nil?
|
26
|
+
|
27
|
+
archive_link = archive_href.attributes['href'].value unless archive_href.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
list << ChannelMediaItem.new(text, link, archive_link)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
list
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class FreetvPage < MediaPage
|
2
|
+
FREETV_URL = BASE_URL + "/freeTV.html"
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
super(FREETV_URL)
|
6
|
+
end
|
7
|
+
|
8
|
+
def category_breadcrumbs
|
9
|
+
[]
|
10
|
+
end
|
11
|
+
|
12
|
+
def items
|
13
|
+
list = []
|
14
|
+
|
15
|
+
document.css("table tr").each do |item|
|
16
|
+
node = item.css("td img")
|
17
|
+
if node.size > 0
|
18
|
+
text = node.at(0).parent.css("a")
|
19
|
+
unless text.to_s.size == 0
|
20
|
+
link = node.at(0).parent.css("a")
|
21
|
+
text = link.at(0).text.gsub(/\s\s+/, ' ')
|
22
|
+
rating_image = node.at(0).attributes['src']
|
23
|
+
image = link.at(0).parent.parent.previous.css("td img").at(0).attributes['src'].value.strip
|
24
|
+
|
25
|
+
href = link.at(0).attributes['href'].value.strip
|
26
|
+
|
27
|
+
record = BrowseMediaItem.new(text, href)
|
28
|
+
record.rating_image = rating_image
|
29
|
+
record.image = image
|
30
|
+
|
31
|
+
list << record
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
list
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class GroupPage < BasePage
|
2
|
+
protected
|
3
|
+
|
4
|
+
def get_typical_items tag_name
|
5
|
+
list = []
|
6
|
+
|
7
|
+
document.css(tag_name).at(0).next.children.each do |table|
|
8
|
+
href = table.css("a").at(0)
|
9
|
+
|
10
|
+
unless href.nil?
|
11
|
+
link = href.attributes['href'].value
|
12
|
+
text = href.children.at(0).content
|
13
|
+
channel = ""
|
14
|
+
|
15
|
+
if link =~ /media/
|
16
|
+
additional_info = additional_info(href, 1)
|
17
|
+
|
18
|
+
channel = additional_info.gsub(/\(|\)/, '') unless additional_info.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
list << GroupMediaItem.new(text, link, channel)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
list
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class BestTenPage < GroupPage
|
30
|
+
def items
|
31
|
+
get_typical_items("#tbl10best")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class PopularPage < GroupPage
|
36
|
+
def items
|
37
|
+
get_typical_items("#tblyearago")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class WeRecommendPage < GroupPage
|
42
|
+
def items
|
43
|
+
get_typical_items("#tblfree")
|
44
|
+
end
|
45
|
+
end
|