syoboi_calendar 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 868119fd5a5b282c5db313b144f77997d4671e15
4
+ data.tar.gz: fcab1aa760c3bdbc41d69fce7020d85f7e300176
5
+ SHA512:
6
+ metadata.gz: bc6f29de1b9c57666a79f4cbc841919809c376a8afca22dd922d95ccc2f28bfda0b03a18a01fcca2321404531ad1ae52d59b7ee057c552bf1c46e1a36fed0e9b
7
+ data.tar.gz: 68755cfc0efbac89a202612f044c187aba095c1b8d2da8a46a3273438a298b46438e2f41f81be0abb556f3443859f3725cbe2a94d160f91d0fc7b9cdb1575495
data/.travis.yml CHANGED
@@ -1,4 +1,8 @@
1
+ branches:
2
+ only:
3
+ - master
1
4
  language: ruby
2
5
  rvm:
3
- - 1.9.2
4
6
  - 1.9.3
7
+ - 2.0.0
8
+ - 2.1.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 0.2.0
2
+ * Remake SyoboiCalendar::Client from scratch
3
+ * Support GET /db.php API
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Ryo NAKAMURA
1
+ Copyright (c) 2014 Ryo NAKAMURA
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,32 +1,99 @@
1
1
  # SyoboiCalendar
2
-
3
- Simple gem for [SyoboiCalendar](http://cal.syoboi.jp/) to search Japanese anime lineup
2
+ Search Japanese anime from [SyoboiCalendar](http://cal.syoboi.jp/).
4
3
 
5
4
  ## Installation
6
-
7
- ```
8
- $ gem install syoboi_calendar
5
+ ```ruby
6
+ # Gemfile
7
+ gem "syoboi_calendar"
9
8
  ```
10
9
 
11
10
  ## Usage
11
+ ```ruby
12
+ require "syoboi_calendar"
12
13
 
14
+ client = SyoboiCalendar::Client
15
+ client.channels #=> [...]
16
+ client.programs #=> [...]
17
+ client.titles #=> [...]
13
18
  ```
14
- require "syoboi_calendar"
15
- require "date"
16
19
 
17
- client = SyoboiCalendar.new(
18
- :user => "r7kamura",
19
- :pass => "********"
20
- )
21
- programs = client.search(
22
- :first => true,
23
- :range => Date.today .. Date.today + 7
24
- )
20
+ ## API
21
+ Supported API request examples:
25
22
 
26
- p programs[0].name #=> "さんかれあ #1 私が…ゾンビに…なったら"
27
- p programs[0].start_time #=> 2012-04-06 02:50:00 +0900
28
- p programs[0].channel_name #=> "TBS"
29
23
  ```
24
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles
25
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&ChID=:channelID
26
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&Count=:count
27
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&PID=:id
28
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&PID=:id
29
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&Range=-:playedTo
30
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&Range=:playedFrom-
31
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&Range=:playedFrom-:playedTo
32
+ GET http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&StTime=-:startedTo
33
+ GET http://cal.syoboi.jp/db.php?Command=TitleLookup
34
+ GET http://cal.syoboi.jp/db.php?Command=TitleLookup&LastUpdate=-:updatedTo&TID=*
35
+ GET http://cal.syoboi.jp/db.php?Command=TitleLookup&LastUpdate=:updatedFrom-&TID=*
36
+ GET http://cal.syoboi.jp/db.php?Command=TitleLookup&LastUpdate=:updatedFrom-:updatedTo&TID=*
37
+ GET http://cal.syoboi.jp/db.php?Command=TitleLookup&TID=:id
38
+ GET http://cal.syoboi.jp/db.php?Command=ChLookup
39
+ GET http://cal.syoboi.jp/db.php?Command=ChLookup&ChID=:id
40
+ GET http://cal.syoboi.jp/db.php?Command=ChLookup&LastUpdate=:updatedFrom-:updatedTo
41
+ GET http://cal.syoboi.jp/db.php?Command=ChLookup&LastUpdate=:updatedFrom-
42
+ GET http://cal.syoboi.jp/db.php?Command=ChLookup&LastUpdate=-:updatedTo
43
+ ```
44
+
45
+ ## Interface
46
+ SyoboiCalender::Client has `#channels`, `#titles`, `#programs` methods.
30
47
 
31
- ## Requirement
32
- * Ruby >= 1.9.2
48
+ ```
49
+ SyoboiCalendar::Client
50
+ #channels
51
+ with options {}
52
+ requests to http://cal.syoboi.jp/db.php?Command=ChLookup
53
+ with options {:channel_id=>1}
54
+ requests to http://cal.syoboi.jp/db.php?ChID=1&Command=ChLookup
55
+ with options {:updated_from=>2000-01-01 00:00:00 UTC}
56
+ requests to http://cal.syoboi.jp/db.php?Command=ChLookup&LastUpdate=20000101_000000-
57
+ with options {:updated_to=>2000-01-01 00:00:00 UTC}
58
+ requests to http://cal.syoboi.jp/db.php?Command=ChLookup&LastUpdate=-20000101_000000
59
+ with options {:updated_from=>2000-01-01 00:00:00 UTC, :updated_to=>2000-01-01 00:00:00 UTC}
60
+ requests to http://cal.syoboi.jp/db.php?Command=ChLookup&LastUpdate=20000101_000000-20000101_000000
61
+ #titles
62
+ with options {}
63
+ requests to http://cal.syoboi.jp/db.php?Command=TitleLookup
64
+ with options {:title_id=>1}
65
+ requests to http://cal.syoboi.jp/db.php?Command=TitleLookup&TID=1
66
+ with options {:updated_from=>2000-01-01 00:00:00 UTC}
67
+ requests to http://cal.syoboi.jp/db.php?Command=TitleLookup&LastUpdate=20000101_000000-
68
+ with options {:updated_to=>2000-01-01 00:00:00 UTC}
69
+ requests to http://cal.syoboi.jp/db.php?Command=TitleLookup&LastUpdate=-20000101_000000
70
+ with options {:updated_from=>2000-01-01 00:00:00 UTC, :updated_to=>2000-01-01 00:00:00 UTC}
71
+ requests to http://cal.syoboi.jp/db.php?Command=TitleLookup&LastUpdate=20000101_000000-20000101_000000
72
+ #programs
73
+ with options {}
74
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles
75
+ with options {:program_id=>1}
76
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&PID=1
77
+ with options {:program_id=>1, :channel_id=>2}
78
+ requests to http://cal.syoboi.jp/db.php?ChID=2&Command=ProgLookup&JOIN=SubTitles&PID=1
79
+ with options {:count=>1}
80
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&Count=1&JOIN=SubTitles
81
+ with options {:updated_from=>2000-01-01 00:00:00 UTC}
82
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&LastUpdate=20000101_000000-
83
+ with options {:updated_to=>2000-01-01 00:00:00 UTC}
84
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&LastUpdate=-20000101_000000
85
+ with options {:updated_from=>2000-01-01 00:00:00 UTC, :updated_to=>2000-01-01 00:00:00 UTC}
86
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&LastUpdate=20000101_000000-20000101_000000
87
+ with options {:started_from=>2000-01-01 00:00:00 UTC}
88
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&StTime=20000101_000000-
89
+ with options {:started_to=>2000-01-01 00:00:00 UTC}
90
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&StTime=-20000101_000000
91
+ with options {:started_from=>2000-01-01 00:00:00 UTC, :started_to=>2000-01-01 00:00:00 UTC}
92
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&StTime=20000101_000000-20000101_000000
93
+ with options {:played_from=>2000-01-01 00:00:00 UTC}
94
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&Range=20000101_000000-
95
+ with options {:played_to=>2000-01-01 00:00:00 UTC}
96
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&Range=-20000101_000000
97
+ with options {:played_from=>2000-01-01 00:00:00 UTC, :played_to=>2000-01-01 00:00:00 UTC}
98
+ requests to http://cal.syoboi.jp/db.php?Command=ProgLookup&JOIN=SubTitles&Range=20000101_000000-20000101_000000
99
+ ```
data/Rakefile CHANGED
@@ -1,26 +1,5 @@
1
- #!/usr/bin/env rake
2
-
3
1
  require "bundler/gem_tasks"
4
-
5
- begin
6
- require "bundler"
7
- rescue LoadError
8
- $stderr.puts e.message
9
- $stderr.puts "Run `gem install bundler` to install bundler"
10
- exit e.status_code
11
- end
12
-
13
- begin
14
- Bundler.setup(:default, :development)
15
- rescue Bundler::BundlerError => e
16
- $stderr.puts e.message
17
- $stderr.puts "Run `bundle install` to install missing gems"
18
- exit e.status_code
19
- end
20
-
21
- require "rspec/core"
22
2
  require "rspec/core/rake_task"
23
3
 
24
4
  RSpec::Core::RakeTask.new(:spec)
25
-
26
- task :default => :spec
5
+ task default: :spec
@@ -1,99 +1,45 @@
1
- class SyoboiCalendar
2
- module Client
3
- # user and pass are optional to search with user's channel setting
4
- def initialize(opts = {})
5
- @agent = Agent.new(:user => opts[:user], :pass => opts[:pass])
1
+ module SyoboiCalendar
2
+ class Client
3
+ attr_reader :options
4
+
5
+ def initialize(options = {})
6
+ @options = options
6
7
  end
7
8
 
8
- def login?
9
- @agent.login?
9
+ def channels(options = {})
10
+ get(Queries::Channel, options)
10
11
  end
11
12
 
12
- # search programs
13
- def search(args)
14
- query = create_search_query(args)
15
- page = @agent.search(query)
13
+ def programs(options = {})
14
+ get(Queries::Program, options)
15
+ end
16
16
 
17
- args[:mode] == :title ?
18
- extract_titles(page) :
19
- extract_programs(page)
17
+ def titles(options = {})
18
+ get(Queries::Title, options)
20
19
  end
21
20
 
22
21
  private
23
22
 
24
- # return Array of #<SyoboiCalendar::Program> by #<Mechanize::Page>
25
- def extract_programs(page, opts = {})
26
- page.search(".tframe tr").map do |tr|
27
- args = {}
28
-
29
- tr.search("td:nth-child(2) a").each do |a|
30
- if match = a.attributes["href"].value.match(%r|/tid/(\d+)/time#(\d+)$|)
31
- args[:tid] = match[1]
32
- args[:pid] = match[2]
33
- args[:name] = a.text
34
- end
35
- end
36
-
37
- tr.search("td:nth-child(3)").each do |td|
38
- args[:channel_name] = td.text
39
- end
40
-
41
- if args.has_key?(:tid)
42
- Program.new(args)
43
- else
44
- nil
45
- end
46
- end.compact
23
+ def get(query_class, options = {})
24
+ connection.get(path, query_class.new(options).to_hash)
47
25
  end
48
26
 
49
- # return Array of #<SyoboiCalendar::Title> by #<Mechanize::Page>
50
- def extract_titles(page, opts = {})
51
- page.search(".tframe tr").map do |tr|
52
- args = {}
53
-
54
- tr.search("td:nth-child(1) a").each do |a|
55
- if match = a.attributes["href"].value.match(%r|/tid/(\d+)$|)
56
- args[:tid] = match[1]
57
- args[:name] = a.text
58
- end
59
- end
60
-
61
- if args.has_key?(:tid)
62
- Title.new(args)
63
- else
64
- nil
65
- end
66
- end.compact
27
+ def connection
28
+ @connection ||= Faraday.new(url: url) do |connection|
29
+ connection.adapter :net_http
30
+ end
67
31
  end
68
32
 
69
- # create hash for search query
70
- def create_search_query(opts)
71
- opts[:range] &&= canonicalize_range(opts[:range])
33
+ def url
34
+ "http://#{host}/"
35
+ end
72
36
 
73
- {
74
- :sd => { nil => 2, :program => 2, :title => 0 }[opts[:mode]],
75
- :r => { nil => 0, :all => 0, :past => 1, :future => 2}[opts[:range]] || 3,
76
- :rd => opts[:range],
77
- :kw => opts[:keyword],
78
- :ch => opts[:channel],
79
- :st => opts[:subtitle],
80
- :cm => opts[:comment],
81
- :uuc => opts[:uuc] || 1, # use user's channel setting
82
- :v => opts[:v] || 0, # list view
83
- :pfn => opts[:first] && 2, # first episode
84
- :pfl => opts[:final] && 4, # final episode
85
- :pfs => opts[:special] && 1, # special program
86
- }.select { |k, v| v }
37
+ def host
38
+ "cal.syoboi.jp"
87
39
  end
88
40
 
89
- def canonicalize_range(range)
90
- if range.kind_of?(Range)
91
- [range.first, range.last].map { |date|
92
- date.strftime("%Y/%m/%d")
93
- }.join("-")
94
- else
95
- range
96
- end
41
+ def path
42
+ "/db.php"
97
43
  end
98
44
  end
99
45
  end
@@ -0,0 +1,77 @@
1
+ module SyoboiCalendar
2
+ module Queries
3
+ class Base
4
+ class << self
5
+ def property(*properties)
6
+ self.properties += properties
7
+ end
8
+
9
+ def option(*options)
10
+ options.each do |option|
11
+ define_method(option) do
12
+ self.options[option]
13
+ end
14
+ end
15
+ end
16
+
17
+ def time_option(*names)
18
+ names.each do |name|
19
+ define_method("has_#{name}_time?") do
20
+ !!(send("#{name}_from") || send("#{name}_to"))
21
+ end
22
+
23
+ define_method("formatted_#{name}_from") do
24
+ send("#{name}_from").try(:strftime, "%Y%m%d_%H%M%S")
25
+ end
26
+
27
+ define_method("formatted_#{name}_to") do
28
+ send("#{name}_to").try(:strftime, "%Y%m%d_%H%M%S")
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ class_attribute :properties
35
+
36
+ self.properties = []
37
+
38
+ option(
39
+ :updated_from,
40
+ :updated_to,
41
+ )
42
+
43
+ time_option(
44
+ :updated,
45
+ )
46
+
47
+ property(
48
+ :Command,
49
+ :LastUpdate,
50
+ )
51
+
52
+ attr_reader :options
53
+
54
+ def initialize(options = {})
55
+ @options = options
56
+ end
57
+
58
+ def to_hash
59
+ to_hash_with_nil_value.reject {|key, value| value.nil? }
60
+ end
61
+
62
+ def to_hash_with_nil_value
63
+ properties.inject({}) do |hash, property|
64
+ hash.merge(property => send(property.to_s.underscore))
65
+ end
66
+ end
67
+
68
+ def properties
69
+ self.class.properties
70
+ end
71
+
72
+ def last_update
73
+ "#{formatted_updated_from}-#{formatted_updated_to}" if has_updated_time?
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,13 @@
1
+ module SyoboiCalendar
2
+ module Queries
3
+ class Channel < Base
4
+ include ChannelIdQueriable
5
+
6
+ private
7
+
8
+ def command
9
+ "ChLookup"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module SyoboiCalendar
2
+ module Queries
3
+ module ChannelIdQueriable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ option :channel_id
8
+
9
+ property :ChID
10
+
11
+ alias ch_id channel_id
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,49 @@
1
+ module SyoboiCalendar
2
+ module Queries
3
+ class Program < Base
4
+ include ChannelIdQueriable
5
+
6
+ option(
7
+ :count,
8
+ :program_id,
9
+ :played_from,
10
+ :played_to,
11
+ :started_from,
12
+ :started_to,
13
+ )
14
+
15
+ time_option(
16
+ :played,
17
+ :started,
18
+ )
19
+
20
+ property(
21
+ :Count,
22
+ :JOIN,
23
+ :PID,
24
+ :Range,
25
+ :StTime,
26
+ )
27
+
28
+ alias pid program_id
29
+
30
+ private
31
+
32
+ def command
33
+ "ProgLookup"
34
+ end
35
+
36
+ def join
37
+ "SubTitles"
38
+ end
39
+
40
+ def range
41
+ "#{formatted_played_from}-#{formatted_played_to}" if has_played_time?
42
+ end
43
+
44
+ def st_time
45
+ "#{formatted_started_from}-#{formatted_started_to}" if has_started_time?
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ module SyoboiCalendar
2
+ module Queries
3
+ class Title < Base
4
+ option :title_id
5
+
6
+ property :TID
7
+
8
+ alias tid title_id
9
+
10
+ private
11
+
12
+ def command
13
+ "TitleLookup"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
- class SyoboiCalendar
2
- VERSION = "0.1.3"
1
+ module SyoboiCalendar
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,13 +1,12 @@
1
- # gems
2
- require "mechanize"
1
+ require "active_support/concern"
2
+ require "active_support/core_ext/class/attribute"
3
+ require "active_support/core_ext/object/try"
4
+ require "active_support/core_ext/string/inflections"
5
+ require "faraday"
3
6
 
4
- # libraries
5
- require "syoboi_calendar/version"
6
- require "syoboi_calendar/agent"
7
- require "syoboi_calendar/title"
8
- require "syoboi_calendar/program"
9
7
  require "syoboi_calendar/client"
10
-
11
- class SyoboiCalendar
12
- include SyoboiCalendar::Client
13
- end
8
+ require "syoboi_calendar/queries/base"
9
+ require "syoboi_calendar/queries/channel_id_queriable"
10
+ require "syoboi_calendar/queries/channel"
11
+ require "syoboi_calendar/queries/program"
12
+ require "syoboi_calendar/queries/title"
data/spec/spec_helper.rb CHANGED
@@ -1,29 +1,11 @@
1
- $LOAD_PATH.unshift File.expand_path("../", __FILE__)
2
- $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
-
4
1
  require "simplecov"
5
2
  SimpleCov.start
6
3
 
7
4
  require "syoboi_calendar"
8
5
  require "webmock/rspec"
9
6
 
10
- WebMock.allow_net_connect!
11
-
12
- module SyoboiCalendar::Fixture
13
- extend self
14
-
15
- FIXTURE_DIR = File.expand_path("../fixtures", __FILE__)
16
-
17
- private
18
-
19
- def method_missing(method_name, *args)
20
- cache[method_name] ||= begin
21
- path = "#{FIXTURE_DIR}/#{method_name}"
22
- File.exist?(path) ? cache[method_name] = File.read(path) : nil
23
- end
24
- end
25
-
26
- def cache
27
- @cache ||= {}
28
- end
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
29
11
  end