etvnet_seek 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,6 @@
1
+
2
+ = Etvnet-seek Gem Changelog
3
+
4
+ == Version 0.1.0
5
+
6
+ * Initial release.
data/README ADDED
@@ -0,0 +1,11 @@
1
+ = Etvnet Seek Gem -- Command line tool for getting mms urls from etvnet service.
2
+
3
+ = Installing Etvnet Seek
4
+
5
+ == Installing the Gem
6
+ $ sudo gem sources -a http://gemcutter.org
7
+ $ sudo gem install etvnet_seek
8
+
9
+ == Usage
10
+
11
+ etvnet_seek movie_title
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ begin
2
+ require 'zip_it'
3
+ rescue LoadError
4
+ puts "Zipit is not available. Install it with: sudo gem install zipit"
5
+ exit
6
+ end
7
+
8
+ task :zip do
9
+ zip :archive => "etvnet_seek.zip", :dir => "."
10
+ end
11
+
12
+ desc "Run gem code locally"
13
+ task :"run:gem" do
14
+ command = "bin/etvnet_seek $1 $2"
15
+ puts ruby("#{command}")
16
+ end
17
+
18
+ task :default => :zip
data/bin/etvnet_seek ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' unless RUBY_VERSION =~ /1.9.*/
4
+
5
+ $:.unshift(File::join(File::dirname(File::dirname(__FILE__)), "lib"))
6
+
7
+ require 'etvnet_seek'
8
+
9
+ client = EtvnetSeek.new
10
+
11
+ items = client.search ARGV.join(' ')
12
+
13
+ client.display_search_items items
14
+
15
+ title_number = ask("Select title : ")
16
+
17
+ dot_index = title_number.index('.')
18
+
19
+ if not dot_index.nil?
20
+ pos1 = title_number[0..dot_index-1].to_i
21
+ pos2 = title_number[dot_index+1..-1].to_i
22
+
23
+ movie_link = client.grab_movie_link items[pos1-1][:container][pos2-1][:link]
24
+ else
25
+ movie_link = client.grab_movie_link items[title_number.to_i-1][:link]
26
+ end
27
+
28
+ puts "Link: #{movie_link}"
29
+
30
+ `open #{movie_link}`
@@ -0,0 +1,6 @@
1
+ @ECHO OFF
2
+ IF NOT "%~f0" == "~f0" GOTO :WinNT
3
+ @"ruby.exe" "C:/Ruby/ruby-1.9.1/bin/etvnet_seek" %1 %2 %3 %4 %5 %6 %7 %8 %9
4
+ GOTO :EOF
5
+ :WinNT
6
+ @"ruby.exe" "%~dpn0" %*
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "rake"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{etvnet_seek}
7
+ s.version = "0.1.0"
8
+
9
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+
11
+ s.authors = ["Alexander Shvets"]
12
+ s.date = %q{2010-02-06}
13
+ s.description = %q{Command line tool for getting mms urls from etvnet service.}
14
+ s.email = %q{alexander.shvets@gmail.com}
15
+
16
+ s.files = FileList["bin/**", "lib/**/*.rb", "spec/**", "CHANGES", "etvnet_seek.gemspec", "Rakefile", "README"]
17
+ s.test_files = FileList["spec/**/*.rb"]
18
+
19
+ s.has_rdoc = true
20
+ s.homepage = %q{http://github.com/shvets/etvnet_seek}
21
+ s.require_paths = ["lib"]
22
+ s.rubyforge_project = %q{etvnet_seek}
23
+ s.rubygems_version = %q{1.3.2}
24
+ s.summary = %q{Command line tool for getting mms urls from etvnet service.}
25
+
26
+ if s.respond_to? :specification_version then
27
+ s.specification_version = 2
28
+ end
29
+
30
+ s.platform = Gem::Platform::RUBY
31
+ s.requirements = ["none"]
32
+ s.executables = ['etvnet_seek']
33
+ s.bindir = "bin"
34
+
35
+ s.add_dependency("json_pure", ">= 1.2.0")
36
+ s.add_dependency("highline", ">= 1.5.1")
37
+ s.add_dependency("nokogiri", ">= 1.3.3")
38
+
39
+ s.add_development_dependency "rspec", ">= 1.2.8"
40
+ s.add_development_dependency "mocha", ">= 0.9.7"
41
+ end
@@ -0,0 +1,93 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module CookieHelper
5
+ def retrieve_cookie url, username, password
6
+ uri = URI.parse(url)
7
+ conn = Net::HTTP.new(uri.host, uri.port)
8
+
9
+ headers = { "Content-Type" => "application/x-www-form-urlencoded" }
10
+ resp, data = conn.post("/cgi-bin/video/login.fcgi",
11
+ "action=login&username=#{username}&pwd=#{password}&skip_notice=&redirect=", headers)
12
+
13
+ cookie = resp.response['set-cookie']
14
+
15
+ cleanup_cookie(cookie)
16
+ end
17
+
18
+ private
19
+
20
+ def cleanup_cookie cookie
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
36
+
37
+ new_cookie
38
+ end
39
+
40
+ def get_auth_and_expires cookie
41
+ length = "auth=".length
42
+
43
+ auth = ""
44
+ expires = ""
45
+
46
+ fragment = cookie
47
+
48
+ while true do
49
+ position = fragment.index("auth=")
50
+
51
+ break if position == -1
52
+
53
+ if fragment[position+length..position+length] != ";"
54
+ right_position = fragment[position..-1].index(";")
55
+ auth = fragment[position+length..position+right_position-1]
56
+
57
+ pos1 = position+right_position+1+"expires=".length+1
58
+ pos2 = fragment[pos1..-1].index(";")
59
+ expires = fragment[pos1..pos1+pos2-1]
60
+ break
61
+ else
62
+ fragment = fragment[position+length+1..-1]
63
+ end
64
+ end
65
+
66
+ [auth, expires]
67
+ end
68
+
69
+ def get_username cookie
70
+ length = "username=".length
71
+
72
+ username = ""
73
+
74
+ fragment = cookie
75
+
76
+ while true do
77
+ position = fragment.index("username=")
78
+
79
+ break if position == -1
80
+
81
+ if fragment[position+length..position+length] != ";"
82
+ right_position = fragment[position..-1].index(";")
83
+ username = fragment[position+length..position+right_position-1]
84
+
85
+ break
86
+ else
87
+ fragment = fragment[position+length+1..-1]
88
+ end
89
+ end
90
+
91
+ username
92
+ end
93
+ end
@@ -0,0 +1,146 @@
1
+ require 'rubygems' unless RUBY_VERSION =~ /1.9.*/
2
+
3
+ require 'nokogiri'
4
+ require 'open-uri'
5
+ #require "readline"
6
+ require "highline/import"
7
+ require 'cgi'
8
+ require 'json'
9
+
10
+ require 'cookie_helper'
11
+
12
+ class EtvnetSeek
13
+ include CookieHelper
14
+
15
+ BASE_URL = "http://www.etvnet.ca"
16
+ SEARCH_URL = BASE_URL + "/cgi-bin/video/eitv_browse.fcgi?action=search"
17
+ ACCESS_URL = BASE_URL + "/cgi-bin/video/access.fcgi"
18
+ LOGIN_URL = BASE_URL + "/cgi-bin/video/login.fcgi"
19
+
20
+ def cookie
21
+ @cookie ||= get_cookie
22
+ end
23
+
24
+ def search keywords, order_direction = '-'
25
+ search_items SEARCH_URL + "&keywords=#{CGI.escape(keywords)}&order_direction=#{order_direction}"
26
+ end
27
+
28
+ def search_items url
29
+ doc = Nokogiri::HTML(open(url))
30
+
31
+ list = []
32
+
33
+ doc.css("table tr[2] td table").each do |item|
34
+ links = item.css(".media_file")
35
+
36
+ links.each_with_index do |link, index|
37
+ if index % 2 != 0
38
+ href = link.attributes['href'].value
39
+
40
+ new_link = list.select {|l| l[:link] == href}.empty?
41
+
42
+ if new_link
43
+ record = {:link => href,
44
+ :name => link.content.strip,
45
+ # :first_time => link.parent.parent.previous.previous.previous.previous.content.strip,
46
+ # :year => link.parent.parent.next.next.content.strip,
47
+ # :how_long => link.parent.parent.next.next.next.next.content.strip
48
+ }
49
+
50
+ if href =~ /action=browse_container/
51
+ record[:container] = search_items(href)
52
+ else
53
+ result = href.match(/(\w*)\/(\w*)\/(\w*)\/([\w|-]*)/)
54
+
55
+ record[:media_file] = (result.size > 2) ? result[3] : ""
56
+ record[:english_name] = (result.size > 3) ? result[4] : ""
57
+ end
58
+
59
+ list << record
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ list
66
+ end
67
+
68
+ def display_search_items items
69
+ items.each_with_index do |item1, index1|
70
+
71
+ if item1[:container].nil?
72
+ puts "#{index1+1}. #{item1[:english_name]} --- #{item1[:media_file]} --- #{item1[:name]}"
73
+ else
74
+ puts "#{index1+1}. #{item1[:name]}"
75
+
76
+ item1[:container].each_with_index do |item2, index2|
77
+ puts " #{index1+1}.#{index2+1}. #{item2[:english_name]} --- #{item2[:media_file]} --- #{item2[:name]}"
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def grab_movie_link link
84
+ result = link.match(/(\w*)\/(\w*)\/(\w*)\/([\w|-]*)/)
85
+
86
+ media_file = (not result.nil? and result.size > 2) ? result[3] : ""
87
+
88
+ media_info = request_media_info media_file, cookie
89
+
90
+ mms_link(media_info)
91
+ end
92
+
93
+ private
94
+
95
+ def get_cookie
96
+ file_name = ENV['HOME'] + "/.etvnet-seek"
97
+
98
+ if File.exist? file_name
99
+ cookie = read_user_file file_name
100
+ else
101
+ username = ask("Enter username : " )
102
+ password = ask("Enter password : " ) { |q| q.echo = '*' }
103
+
104
+ cookie = retrieve_cookie LOGIN_URL, username, password
105
+
106
+ write_user_file file_name, cookie
107
+ end
108
+
109
+ cookie
110
+ end
111
+
112
+ def read_user_file file_name
113
+ File.open(file_name, 'r') do |file|
114
+ return file.gets
115
+ end
116
+ end
117
+
118
+ def write_user_file file_name, cookie
119
+ File.open(file_name, 'w') do |file|
120
+ file.puts cookie
121
+ end
122
+ end
123
+
124
+ def request_media_info media_file, cookie
125
+ url = URI.parse(ACCESS_URL)
126
+ conn = Net::HTTP.new(url.host, url.port)
127
+
128
+ headers = { 'Cookie' => cookie }
129
+
130
+ request = Net::HTTP::Post.new(url.request_uri, headers)
131
+
132
+ request.set_form_data(
133
+ { 'action' => 'start_video', 'bitrate' => '600',
134
+ 'media_file'=> media_file, 'replay' => '1', 'skin' => 'JSON'
135
+ }
136
+ )
137
+
138
+ response = conn.request(request)
139
+
140
+ response.body
141
+ end
142
+
143
+ def mms_link media_info
144
+ JSON.parse(media_info)["PARAMETERS"]["REDIRECT_URL"]
145
+ end
146
+ end
@@ -0,0 +1,23 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'rubygems' unless RUBY_VERSION =~ /1.9.*/
4
+
5
+ #require 'spec'
6
+
7
+ require 'etvnet_seek'
8
+
9
+ describe EtvnetSeek do
10
+
11
+ before :each do
12
+ @client = EtvnetSeek.new
13
+ end
14
+
15
+ it "should return search menu items" do
16
+ keywords = "красная шапочка"
17
+
18
+ @client.search(keywords).size.should > 0
19
+ items = @client.search(keywords)
20
+ @client.display_search_items items
21
+ end
22
+
23
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: etvnet_seek
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Shvets
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-06 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json_pure
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: highline
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.1
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: nokogiri
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.3.3
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: rspec
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.2.8
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 0.9.7
64
+ version:
65
+ description: Command line tool for getting mms urls from etvnet service.
66
+ email: alexander.shvets@gmail.com
67
+ executables:
68
+ - etvnet_seek
69
+ extensions: []
70
+
71
+ extra_rdoc_files: []
72
+
73
+ files:
74
+ - bin/etvnet_seek
75
+ - bin/etvnet_seek.bat
76
+ - lib/cookie_helper.rb
77
+ - lib/etvnet_seek.rb
78
+ - spec/etvnet_seek_spec.rb
79
+ - spec/spec.opts
80
+ - CHANGES
81
+ - etvnet_seek.gemspec
82
+ - Rakefile
83
+ - README
84
+ has_rdoc: true
85
+ homepage: http://github.com/shvets/etvnet_seek
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options: []
90
+
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ requirements:
106
+ - none
107
+ rubyforge_project: etvnet_seek
108
+ rubygems_version: 1.3.5
109
+ signing_key:
110
+ specification_version: 2
111
+ summary: Command line tool for getting mms urls from etvnet service.
112
+ test_files:
113
+ - spec/etvnet_seek_spec.rb