etvnet_seek 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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