myshows 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ A 첮
2
+ ����Y�!�}�������ӂ�M�u't�7��W�ϴ�%Sf}�C,�u�_ LF�>l��wH����3�Vz`��^#�ٍG|p��w�L>6wPrި^[,����`�8FB>FY'=-5�+.�;��p.�q9�8(����^,��pڞ�!B/`����=\��xp�i#<w|����ju�,������M�� �g�[]����#�>L��er{����tR4*�u��p��m֖#K�}�05��I0
@@ -0,0 +1,12 @@
1
+ Manifest
2
+ README
3
+ Rakefile
4
+ lib/myshows.rb
5
+ lib/myshows/api.rb
6
+ lib/myshows/episode.rb
7
+ lib/myshows/item.rb
8
+ lib/myshows/profile.rb
9
+ lib/myshows/search.rb
10
+ lib/myshows/show.rb
11
+ myshows.gemspec
12
+ spec/myshows_spec.rb
data/README ADDED
File without changes
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('myshows', '0.1.0') do |p|
6
+ p.summary = "MyShows API"
7
+ p.description = "Object-oriented wrapper over API of http://myshows.ru"
8
+ p.url = "http://github.com/cypok/myshows"
9
+ p.author = "Vladimir Parfinenko"
10
+ p.email = "vladimir.parfinenko@gmail.com"
11
+ p.ignore_pattern = ["tmp/*", "script/*"]
12
+ p.runtime_dependencies = ["httparty", "crack", "memoize"]
13
+ p.development_dependencies = ["rspec"]
14
+ end
15
+
@@ -0,0 +1,8 @@
1
+ $: << File.expand_path(File.dirname(__FILE__))
2
+
3
+ module MyShows
4
+ autoload :Profile, 'myshows/profile'
5
+ autoload :Search, 'myshows/search'
6
+
7
+ class Error < StandardError; end
8
+ end
@@ -0,0 +1,123 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+ require 'crack/json'
4
+ require 'memoize'
5
+ require 'singleton'
6
+
7
+ JSON = Crack::JSON
8
+
9
+ module MyShows
10
+ autoload :Show, 'myshows/show'
11
+ autoload :Episode, 'myshows/episode'
12
+
13
+ class API
14
+ include Singleton
15
+
16
+ include HTTParty
17
+ base_uri 'http://api.myshows.ru'
18
+
19
+ include Memoize
20
+
21
+ def initialize
22
+ %w{search user_shows show_episodes}.each {|m| memoize m }
23
+ end
24
+
25
+ def authorize(login, password)
26
+ res = get '/profile/login', :login => login, :password => password
27
+ error "login or password is incorrect while authorization" if res.code == 403
28
+ error "unknown error while authorization" if res.code != 200
29
+
30
+ self.class.cookies.add_cookies res.headers["set-cookie"]
31
+ end
32
+
33
+ # Returns checked episode
34
+ #def check(name, season_number, episode_number)
35
+ #shows = search name, :only_user => true
36
+ #error "could not find show \"#{name}\" or it is not marked as 'watching'" if shows.count == 0
37
+ #error "ambiguous name \"#{name}\", looks like #{shows.take(2) * ', '}" if shows.count > 1
38
+
39
+ #show = shows.first
40
+ #episodes = show_episodes show
41
+ #episode = episodes.detect { |e| e.season_number == season_number && e.episode_number == episode_number }
42
+ #error "could not find episode #{season_number}x#{episode_number} of show #{show}" if episode.nil?
43
+
44
+ #check_episode episode
45
+
46
+ #episode
47
+ #end
48
+
49
+ # Returns all user shows
50
+ def user_shows
51
+ res = get '/profile/shows/'
52
+ error "authorization problems while getting user shows" if res.code == 401
53
+ error "unknown error while getting user shows" if res.code != 200
54
+
55
+ json2shows res.body
56
+ end
57
+
58
+ # Returns array of found shows
59
+ def search_show(name)
60
+ res = get '/shows/search/', :q => name
61
+ return [] if res.code == 404
62
+ error "unknown error while searching show \"#{name}\"" if res.code != 200
63
+
64
+ found_shows = json2shows res.body
65
+ end
66
+
67
+ # Returns episodes of given show
68
+ def show_episodes(show)
69
+ res = get "/shows/#{show.id}"
70
+ error "could not find show #{show} while getting its episodes" if res.code == 404
71
+ error "unknown error while getting episodes of show #{show}" if res.code != 200
72
+
73
+ json2episodes res.body, show
74
+ end
75
+
76
+ # Checks given episode as watched
77
+ def check_episode(episode)
78
+ res = get "/profile/episodes/check/#{episode.id}"
79
+ error "authorization problems while checking episode #{episode}" if res.code == 401
80
+ error "unknown error while checking episode #{episode}" if res.code != 200
81
+
82
+ episode
83
+ end
84
+
85
+ # Unchecks given episode as watched
86
+ def uncheck_episode(episode)
87
+ res = get "/profile/episodes/uncheck/#{episode.id}"
88
+ error "authorization problems while unchecking episode #{episode}" if res.code == 401
89
+ error "unknown error while unchecking episode #{episode}" if res.code != 200
90
+
91
+ episode
92
+ end
93
+
94
+ protected
95
+
96
+ def json2shows(json)
97
+ JSON.parse(json).map {|id, data| MyShows::Show.new id, data }
98
+ end
99
+
100
+ def json2episodes(json, show)
101
+ JSON.parse(json)['episodes'].map {|id, data| MyShows::Episode.new id, data, show }
102
+ end
103
+
104
+ def error(msg)
105
+ raise MyShows::Error.new msg
106
+ end
107
+
108
+ private
109
+
110
+ def get(url, opts = {})
111
+ #puts "GET url: " + url + " opts: " + make_options(opts).inspect
112
+ self.class.get url, make_options(opts)
113
+ end
114
+
115
+ def post(url, opts = {})
116
+ self.class.post url, make_options(opts)
117
+ end
118
+
119
+ def make_options(opts = {})
120
+ {:query => opts}
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,29 @@
1
+ module MyShows
2
+ autoload :Item, 'myshows/item'
3
+
4
+ class Episode < Item
5
+ attr_reader :show
6
+
7
+ def initialize(id, data, show)
8
+ super(id, data)
9
+
10
+ @show = show
11
+
12
+ [:id, :show, :title, :season_number, :episode_number].each do |f|
13
+ raise ArgumentError.new("#{f} could not be nil") if send(f).nil?
14
+ end
15
+ end
16
+
17
+ def to_s
18
+ "#{show} - #{season_number}x#{episode_number} - #{title}"
19
+ end
20
+
21
+ def check!
22
+ @api.check_episode self
23
+ end
24
+
25
+ def uncheck!
26
+ @api.uncheck_episode self
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ module MyShows
2
+ class Item
3
+ attr_reader :id
4
+
5
+ def initialize(id, data)
6
+ @api = MyShows::API.instance
7
+
8
+ @id = id
9
+ @data = data
10
+ end
11
+
12
+ def method_missing(name, *args)
13
+ return super(name, *args) if args.count > 0
14
+
15
+ # convert to camel case
16
+ cc_name = name.to_s.gsub(/_[a-z]/) {|a| a.upcase }.gsub '_', ''
17
+
18
+ @data[cc_name] or super(name)
19
+ end
20
+
21
+ def ==(other)
22
+ self.class == other.class && self.id == other.id
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module MyShows
2
+ autoload :API, 'myshows/api'
3
+
4
+ class Profile
5
+
6
+ def initialize(login, password)
7
+ @api = MyShows::API.instance
8
+
9
+ @api.authorize login, password
10
+ end
11
+
12
+ def shows
13
+ @api.user_shows
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module MyShows
2
+ autoload :API, 'myshows/api'
3
+
4
+ # Tools for searching over whole base
5
+ class Search
6
+ def initialize
7
+ @api = MyShows::API.instance
8
+ end
9
+
10
+ def show(name)
11
+ @api.search_show name
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ module MyShows
2
+ autoload :Item, 'myshows/item'
3
+
4
+ class Show < Item
5
+ def initialize(id, data)
6
+ super(id, data)
7
+
8
+ [:id, :title].each do |f|
9
+ raise ArgumentError.new("#{f} could not be nil") if send(f).nil?
10
+ end
11
+ end
12
+
13
+ def to_s
14
+ title
15
+ end
16
+
17
+ def episodes
18
+ @api.show_episodes self
19
+ end
20
+
21
+ def episode(season_number, episode_number)
22
+ episodes.detect {|e| e.season_number == season_number && e.episode_number == episode_number }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{myshows}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Vladimir Parfinenko"]
9
+ s.cert_chain = ["/Users/cypok/.gem/gem-public_cert.pem"]
10
+ s.date = %q{2011-01-25}
11
+ s.description = %q{Object-oriented wrapper over API of http://myshows.ru}
12
+ s.email = %q{vladimir.parfinenko@gmail.com}
13
+ s.extra_rdoc_files = ["README", "lib/myshows.rb", "lib/myshows/api.rb", "lib/myshows/episode.rb", "lib/myshows/item.rb", "lib/myshows/profile.rb", "lib/myshows/search.rb", "lib/myshows/show.rb"]
14
+ s.files = ["Manifest", "README", "Rakefile", "lib/myshows.rb", "lib/myshows/api.rb", "lib/myshows/episode.rb", "lib/myshows/item.rb", "lib/myshows/profile.rb", "lib/myshows/search.rb", "lib/myshows/show.rb", "myshows.gemspec", "spec/myshows_spec.rb"]
15
+ s.homepage = %q{http://github.com/cypok/myshows}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Myshows", "--main", "README"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{myshows}
19
+ s.rubygems_version = %q{1.4.2}
20
+ s.signing_key = %q{/Users/cypok/.gem/gem-private_key.pem}
21
+ s.summary = %q{MyShows API}
22
+
23
+ if s.respond_to? :specification_version then
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
28
+ s.add_runtime_dependency(%q<crack>, [">= 0"])
29
+ s.add_runtime_dependency(%q<memoize>, [">= 0"])
30
+ s.add_development_dependency(%q<rspec>, [">= 0"])
31
+ else
32
+ s.add_dependency(%q<httparty>, [">= 0"])
33
+ s.add_dependency(%q<crack>, [">= 0"])
34
+ s.add_dependency(%q<memoize>, [">= 0"])
35
+ s.add_dependency(%q<rspec>, [">= 0"])
36
+ end
37
+ else
38
+ s.add_dependency(%q<httparty>, [">= 0"])
39
+ s.add_dependency(%q<crack>, [">= 0"])
40
+ s.add_dependency(%q<memoize>, [">= 0"])
41
+ s.add_dependency(%q<rspec>, [">= 0"])
42
+ end
43
+ end
@@ -0,0 +1,77 @@
1
+ require 'myshows'
2
+ require 'myshows/show'
3
+ require 'myshows/episode'
4
+
5
+ describe MyShows do
6
+ TBBT = 'The Big Bang Theory'
7
+
8
+ describe MyShows::Profile do
9
+ before :all do
10
+ @profile = MyShows::Profile.new 'demo', 'fe01ce2a7fbac8fafaed7c982a04e229'
11
+ end
12
+
13
+ it "should return user shows" do
14
+ @profile.shows.map(&:title).should include TBBT
15
+ end
16
+ end
17
+
18
+ describe MyShows::Search do
19
+ before :all do
20
+ @search = MyShows::Search.new
21
+ end
22
+
23
+ it "should find popular show" do
24
+ found = @search.show TBBT
25
+ found.map(&:title).should == [TBBT]
26
+ end
27
+
28
+ it "should not find unknown show" do
29
+ found = @search.show 'Some unkown show'
30
+ found.should == []
31
+ end
32
+ end
33
+
34
+ describe MyShows::Show do
35
+ before :all do
36
+ @show = MyShows::Search.new.show(TBBT).first
37
+ end
38
+
39
+ it "should have title" do
40
+ @show.title.should == TBBT
41
+ end
42
+
43
+ it "should have episodes" do
44
+ @show.episodes.should have_at_least(10).items
45
+ end
46
+
47
+ it "should find episode by season and episode number" do
48
+ e = @show.episode(1, 2)
49
+ e.season_number.should == 1
50
+ e.episode_number.should == 2
51
+ end
52
+ end
53
+
54
+ describe MyShows::Episode do
55
+ before :all do
56
+ @episode = MyShows::Search.new.show(TBBT).first.episode(1,1)
57
+ end
58
+
59
+ it "should be connected with show" do
60
+ @episode.show.title.should == TBBT
61
+ end
62
+
63
+ it "should have title, season and episode number" do
64
+ @episode.title.should == "Pilot"
65
+ @episode.season_number.should == 1
66
+ @episode.episode_number.should == 1
67
+ end
68
+
69
+ it "should be checkable" do
70
+ @episode.check!
71
+ end
72
+
73
+ it "should be uncheckable" do
74
+ @episode.uncheck!
75
+ end
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: myshows
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Vladimir Parfinenko
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain:
17
+ - |
18
+ -----BEGIN CERTIFICATE-----
19
+ MIIDSDCCAjCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBKMRwwGgYDVQQDDBN2bGFk
20
+ aW1pci5wYXJmaW5lbmtvMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
21
+ k/IsZAEZFgNjb20wHhcNMTAwOTE1MDg0MTM2WhcNMTEwOTE1MDg0MTM2WjBKMRww
22
+ GgYDVQQDDBN2bGFkaW1pci5wYXJmaW5lbmtvMRUwEwYKCZImiZPyLGQBGRYFZ21h
23
+ aWwxEzARBgoJkiaJk/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
24
+ ggEKAoIBAQCvZkpRSuCHyoPAGvQzWo6JTxJIYpPglVbJalWLUouWhcGewCFcoGpy
25
+ jSkyG1nFUa2AdfEf9x39ZJeRRN7rbH1pcWsXbyMXojWjJ6XhjPL7IlWR1U70qYKO
26
+ c27RdnFhtnd7acXkx/tPrOk/Z/MYVdl9zYXa1gT+uXIWd+M/CS8sRgjSsf3Uxty/
27
+ hObfwgNzWcBCC2iLbi+WTWrvAqO6nj9uRiktEowVH3hUQeg0RQ5PALtmwEGxlfJ6
28
+ HtcL7sKP5lGUkJ8/ZDUofOgkatJmA8V98Qpz3SSEGbPcGw9vtm2lKThwb/6BJ8mO
29
+ fsBh9jiK1ccDVCJmtSJpsIBfxgIyZz7zAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYD
30
+ VR0PBAQDAgSwMB0GA1UdDgQWBBTPzkzZ+7oNX5uWByxqDPaCcxL2izANBgkqhkiG
31
+ 9w0BAQUFAAOCAQEAd0d1BgRz8j+M599IbrQtJOE7IwcmmKM7oQ36mtfb/+MpMZtt
32
+ AI6gbwF5mO9PgWduOjsefH0YI54gjbEH5LeU+eX18WyZPjFtPPQA9oV2e87EcLMU
33
+ N9DLKwhaZrZw0Hkpj9RxguPmoOKds8sRK9OLg1iiLx42sLQ+T6eIn5g0y6QHN9fW
34
+ f8O73LNFaCcG5dfl0dQU0gjJEJ4OsgSpSob1Vxhcoz6U1XTQmj7ZUqMn5qKq9Nh0
35
+ a2F49GO07YddCacBqSjA4DZoQxVsdruI7dtOcvHYvoOB8tY7Ue9XKPcRcyyZa6XN
36
+ 78F0qvtLjR0DAnN6uYs98PR+jHE+0ckLX3D9sw==
37
+ -----END CERTIFICATE-----
38
+
39
+ date: 2011-01-25 00:00:00 +06:00
40
+ default_executable:
41
+ dependencies:
42
+ - !ruby/object:Gem::Dependency
43
+ name: httparty
44
+ prerelease: false
45
+ requirement: &id001 !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ type: :runtime
55
+ version_requirements: *id001
56
+ - !ruby/object:Gem::Dependency
57
+ name: crack
58
+ prerelease: false
59
+ requirement: &id002 !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ type: :runtime
69
+ version_requirements: *id002
70
+ - !ruby/object:Gem::Dependency
71
+ name: memoize
72
+ prerelease: false
73
+ requirement: &id003 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ type: :runtime
83
+ version_requirements: *id003
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ prerelease: false
87
+ requirement: &id004 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :development
97
+ version_requirements: *id004
98
+ description: Object-oriented wrapper over API of http://myshows.ru
99
+ email: vladimir.parfinenko@gmail.com
100
+ executables: []
101
+
102
+ extensions: []
103
+
104
+ extra_rdoc_files:
105
+ - README
106
+ - lib/myshows.rb
107
+ - lib/myshows/api.rb
108
+ - lib/myshows/episode.rb
109
+ - lib/myshows/item.rb
110
+ - lib/myshows/profile.rb
111
+ - lib/myshows/search.rb
112
+ - lib/myshows/show.rb
113
+ files:
114
+ - Manifest
115
+ - README
116
+ - Rakefile
117
+ - lib/myshows.rb
118
+ - lib/myshows/api.rb
119
+ - lib/myshows/episode.rb
120
+ - lib/myshows/item.rb
121
+ - lib/myshows/profile.rb
122
+ - lib/myshows/search.rb
123
+ - lib/myshows/show.rb
124
+ - myshows.gemspec
125
+ - spec/myshows_spec.rb
126
+ has_rdoc: true
127
+ homepage: http://github.com/cypok/myshows
128
+ licenses: []
129
+
130
+ post_install_message:
131
+ rdoc_options:
132
+ - --line-numbers
133
+ - --inline-source
134
+ - --title
135
+ - Myshows
136
+ - --main
137
+ - README
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ hash: 3
146
+ segments:
147
+ - 0
148
+ version: "0"
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ hash: 11
155
+ segments:
156
+ - 1
157
+ - 2
158
+ version: "1.2"
159
+ requirements: []
160
+
161
+ rubyforge_project: myshows
162
+ rubygems_version: 1.4.2
163
+ signing_key:
164
+ specification_version: 3
165
+ summary: MyShows API
166
+ test_files: []
167
+
Binary file