myshows 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.
@@ -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