kandianying 0.0.7 → 0.0.8
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.
- checksums.yaml +4 -4
- data/kandianying.gemspec +1 -0
- data/lib/kandianying/ambassador.rb +11 -36
- data/lib/kandianying/ambassador_scrape.rb +48 -0
- data/lib/kandianying/{vieshow_search.rb → search.rb} +2 -2
- data/lib/kandianying/version.rb +2 -2
- data/lib/kandianying/vieshow.rb +2 -2
- data/spec/ambassador_spec.rb +48 -7
- data/spec/fixtures/ambassador_name_38897fa9-094f-4e63-9d6d-c52408438cb6.yml +2 -5
- data/spec/fixtures/ambassador_name_5c2d4697-7f54-4955-800c-7b3ad782582c.yml +9 -0
- data/spec/fixtures/ambassador_table_38897fa9-094f-4e63-9d6d-c52408438cb6.yml +130 -67
- data/spec/fixtures/ambassador_table_5c2d4697-7f54-4955-800c-7b3ad782582c.yml +304 -0
- data/spec/fixtures/vcr_cassettes/ambassador_name_38897fa9-094f-4e63-9d6d-c52408438cb6.yml +1456 -8515
- data/spec/fixtures/vcr_cassettes/ambassador_name_5c2d4697-7f54-4955-800c-7b3ad782582c.yml +2609 -0
- data/spec/fixtures/vcr_cassettes/ambassador_table_38897fa9-094f-4e63-9d6d-c52408438cb6.yml +1456 -8515
- data/spec/fixtures/vcr_cassettes/ambassador_table_5c2d4697-7f54-4955-800c-7b3ad782582c.yml +2609 -0
- data/spec/fixtures/vcr_cassettes/vieshow_name_05.yml +221 -167
- data/spec/fixtures/vcr_cassettes/vieshow_name_12.yml +174 -127
- data/spec/fixtures/vcr_cassettes/vieshow_table_05.yml +221 -167
- data/spec/fixtures/vcr_cassettes/vieshow_table_12.yml +174 -127
- data/spec/fixtures/vieshow_name_05.yml +7 -11
- data/spec/fixtures/vieshow_name_12.yml +5 -6
- data/spec/fixtures/vieshow_table_05.yml +414 -279
- data/spec/fixtures/vieshow_table_12.yml +334 -237
- data/spec/support/vcr_setup.rb +15 -0
- data/spec/vieshow_spec.rb +1 -12
- metadata +26 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d16fe1b8b27ad6f575ed6e12b92e244dd64c4402
|
4
|
+
data.tar.gz: ac70497b5450250a5d9ad9a5e3c3ad19b0802fe0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6837f76db4416653311efa7dc798e13acb18f54f75a0274c7a6ed91ad1f0dfcba029fcf0871bd01c0f9d40b020ee4310a612a6791a2050cf460726118313d832
|
7
|
+
data.tar.gz: 4765e731a2c172515b740650bb60338460470dec84b688ab489ff0015f04d81a0a0037db3e987607c745b21085d820964c6559fa62fd8607a0a2b7c995afd4cd
|
data/kandianying.gemspec
CHANGED
@@ -2,55 +2,30 @@ require 'open-uri'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'json'
|
4
4
|
require 'yaml'
|
5
|
+
require 'concurrent'
|
6
|
+
require_relative 'ambassador_scrape'
|
7
|
+
require_relative 'search'
|
5
8
|
|
6
9
|
# Scraper for Ambassador
|
7
10
|
module Ambassador
|
8
|
-
AMBASSADOR_THEATER_ID_URL = 'http://www.ambassador.com.tw/showtime_list.html'
|
9
|
-
AMBASSADOR_THEATER_ID_XPATH = "//*[@class='list-group sidebar-nav-v1']//li//a"
|
10
|
-
AMBASSADOR_TIME_API = 'http://cinemaservice.ambassador.com.tw/ambassadorsite.webapi/api/Movies/GetScreeningDateListForTheater/?'
|
11
|
-
AMBASSADOR_FILM_API = 'http://cinemaservice.ambassador.com.tw/ambassadorsite.webapi/api/Movies/GetShowtimeListForTheater/?'
|
12
11
|
# Class for Vieshow films
|
13
12
|
class Ambassador
|
14
|
-
|
15
|
-
attr_reader :theater_id_table
|
16
|
-
|
13
|
+
include AmbassadorScrape, Search
|
14
|
+
attr_reader :movie_table, :theater_id_table, :cinema_name
|
15
|
+
|
16
|
+
def initialize(id)
|
17
17
|
@movie_table = {}
|
18
18
|
@theater_id_table = fetch_theater_id_table(AMBASSADOR_THEATER_ID_URL)
|
19
19
|
theater_id_table.each do |theater_id, theater_name|
|
20
|
+
next unless theater_id.include? id
|
20
21
|
date_list = fetch_theater_date(theater_id)
|
22
|
+
@cinema_name = theater_name
|
21
23
|
@movie_table[theater_name] = fetch_movie_info(theater_id, date_list)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
def
|
26
|
-
|
27
|
-
date_list.each do |date|
|
28
|
-
ur = "#{AMBASSADOR_FILM_API}theaterId=#{theater_id}&showingDate=#{date}"
|
29
|
-
movies = JSON.parse(Nokogiri::HTML(open(ur)).text)
|
30
|
-
movies.each do |movie|
|
31
|
-
name = movie['ForeignName']
|
32
|
-
time = movie['PeriodShowtime'].first['Showtimes']
|
33
|
-
movie_info[name][date] = time
|
34
|
-
end
|
35
|
-
end
|
36
|
-
movie_info
|
37
|
-
end
|
38
|
-
|
39
|
-
def fetch_theater_date(theater_id)
|
40
|
-
url = "#{AMBASSADOR_TIME_API}theaterId=#{theater_id}"
|
41
|
-
JSON.parse(Nokogiri::HTML(open(url)).text)
|
42
|
-
end
|
43
|
-
|
44
|
-
def fetch_theater_id_table(url)
|
45
|
-
theater_id_list = {}
|
46
|
-
open_doc = Nokogiri::HTML(open(url))
|
47
|
-
theater = open_doc.xpath(AMBASSADOR_THEATER_ID_XPATH)
|
48
|
-
theater.each do |t|
|
49
|
-
theater_id = t.attributes['href'].value.split("'")[1]
|
50
|
-
theater_name = t.text
|
51
|
-
theater_id_list[theater_id] = theater_name
|
52
|
-
end
|
53
|
-
theater_id_list
|
27
|
+
def movie_names
|
28
|
+
@movie_table.values[0].keys
|
54
29
|
end
|
55
30
|
|
56
31
|
def to_json
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Helper module to get data from Ambassador
|
2
|
+
module AmbassadorScrape
|
3
|
+
AMBASSADOR_THEATER_ID_URL = 'http://www.ambassador.com.tw/showtime_list.html'
|
4
|
+
AMBASSADOR_THEATER_ID_XPATH = "//*[@class='list-group sidebar-nav-v1']//li//a"
|
5
|
+
AMBASSADOR_TIME_API = 'http://cinemaservice.ambassador.com.tw/ambassadorsite.webapi/api/Movies/GetScreeningDateListForTheater/?'
|
6
|
+
AMBASSADOR_FILM_API = 'http://cinemaservice.ambassador.com.tw/ambassadorsite.webapi/api/Movies/GetShowtimeListForTheater/?'
|
7
|
+
|
8
|
+
def fetch_movie_info(theater_id, date_list)
|
9
|
+
movie_info = Hash.new { |hash, key| hash[key] = {} }
|
10
|
+
date_list.map do |date|
|
11
|
+
url = "#{AMBASSADOR_FILM_API}theaterId=#{theater_id}&showingDate=#{date}"
|
12
|
+
# concurrent_retrieve_info(url, date, movie_info)
|
13
|
+
JSON.parse(Nokogiri::HTML(open(url)).text).map do |movie|
|
14
|
+
name = movie['ForeignName']
|
15
|
+
time = movie['PeriodShowtime'].first['Showtimes']
|
16
|
+
movie_info[name][date] = time
|
17
|
+
end
|
18
|
+
end # .map(&:execute).map(&:value)
|
19
|
+
movie_info # .sort.to_h
|
20
|
+
end
|
21
|
+
|
22
|
+
def concurrent_retrieve_info(url, date, movie_info)
|
23
|
+
Concurrent::Future.new do
|
24
|
+
JSON.parse(Nokogiri::HTML(open(url)).text).map do |movie|
|
25
|
+
name = movie['ForeignName']
|
26
|
+
time = movie['PeriodShowtime'].first['Showtimes']
|
27
|
+
movie_info[name][date] = time
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def fetch_theater_date(theater_id)
|
33
|
+
url = "#{AMBASSADOR_TIME_API}theaterId=#{theater_id}"
|
34
|
+
JSON.parse(Nokogiri::HTML(open(url)).text)
|
35
|
+
end
|
36
|
+
|
37
|
+
def fetch_theater_id_table(url)
|
38
|
+
theater_id_list = {}
|
39
|
+
open_doc = Nokogiri::HTML(open(url))
|
40
|
+
theater = open_doc.xpath(AMBASSADOR_THEATER_ID_XPATH)
|
41
|
+
theater.each do |t|
|
42
|
+
theater_id = t.attributes['href'].value.split("'")[1]
|
43
|
+
theater_name = t.text
|
44
|
+
theater_id_list[theater_id] = theater_name
|
45
|
+
end
|
46
|
+
theater_id_list
|
47
|
+
end
|
48
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Helper module to search for films
|
2
|
-
module
|
2
|
+
module Search
|
3
3
|
NO_FILM = 'Film currently not on show'
|
4
4
|
AN_HOUR = 1 / 24.to_f
|
5
5
|
TIMEZONE = '+8'
|
@@ -32,7 +32,7 @@ module VieshowSearch
|
|
32
32
|
def time_after(date, times, time_preferrence)
|
33
33
|
times.select do |time|
|
34
34
|
time if (MIDNIGHT.include? time[0..1]) ||
|
35
|
-
(DateTime.parse("#{date}#{time}#{TIMEZONE}") >= time_preferrence)
|
35
|
+
(DateTime.parse("#{date} #{time}#{TIMEZONE}") >= time_preferrence)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
data/lib/kandianying/version.rb
CHANGED
data/lib/kandianying/vieshow.rb
CHANGED
@@ -2,7 +2,7 @@ require 'open-uri'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'json'
|
4
4
|
require_relative './vieshow_scrape'
|
5
|
-
require_relative './
|
5
|
+
require_relative './search'
|
6
6
|
|
7
7
|
# Scraper for VieShow
|
8
8
|
module VieShow
|
@@ -10,7 +10,7 @@ module VieShow
|
|
10
10
|
|
11
11
|
# Class for Vieshow films
|
12
12
|
class Vieshow
|
13
|
-
include VieshowScrape,
|
13
|
+
include VieshowScrape, Search
|
14
14
|
# initialize movie_table with ID
|
15
15
|
def initialize(vis_cinema_id)
|
16
16
|
vis_cinema_id = vis_cinema_id.to_s
|
data/spec/ambassador_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require './spec/support/vcr_setup'
|
2
2
|
|
3
|
-
AMBASSADOR_TEST_SITES = %w(38897fa9-094f-4e63-9d6d-c52408438cb6
|
3
|
+
AMBASSADOR_TEST_SITES = %w(38897fa9-094f-4e63-9d6d-c52408438cb6
|
4
|
+
5c2d4697-7f54-4955-800c-7b3ad782582c)
|
4
5
|
# FAIL_SITES = %w(0 16)
|
5
6
|
AMBASSADOR_FIXTURES = './spec/fixtures/ambassador_'
|
6
7
|
|
@@ -8,24 +9,64 @@ describe 'Get film information' do
|
|
8
9
|
AMBASSADOR_TEST_SITES.each do |site|
|
9
10
|
it "must return same list of movies for #{site}" do
|
10
11
|
VCR.use_cassette("ambassador_name_#{site}") do
|
11
|
-
cinema = HsinChuMovie::Ambassador.new
|
12
|
-
name = cinema.theater_id_table[site]
|
12
|
+
cinema = HsinChuMovie::Ambassador.new site
|
13
13
|
site_names = yml_load("#{AMBASSADOR_FIXTURES}name_#{site}.yml")
|
14
|
-
site_names.must_equal cinema.
|
14
|
+
site_names.must_equal cinema.movie_names
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
it "must return same table for #{site}" do
|
19
19
|
VCR.use_cassette("ambassador_table_#{site}") do
|
20
|
-
cinema = HsinChuMovie::Ambassador.new
|
21
|
-
name = cinema.theater_id_table[site]
|
20
|
+
cinema = HsinChuMovie::Ambassador.new site
|
22
21
|
site_table = yml_load("#{AMBASSADOR_FIXTURES}table_#{site}.yml")
|
23
|
-
site_table.must_equal cinema.movie_table
|
22
|
+
site_table.must_equal cinema.movie_table
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
28
|
+
describe 'Get films after a given time on given day' do
|
29
|
+
AMBASSADOR_TEST_SITES.each do |site|
|
30
|
+
it "should only return films after a time for #{site}" do
|
31
|
+
VCR.use_cassette("ambassador_table_#{site}") do
|
32
|
+
cinema = HsinChuMovie::Ambassador.new site
|
33
|
+
time = DateTime.now.new_offset(TAIWAN_TIME)
|
34
|
+
time += GIVEN_DAY.sample
|
35
|
+
time_s = time.to_s
|
36
|
+
time_s[SEC_PART] = ZERO_SEC
|
37
|
+
day_films = cinema.films_on_day(time_s)
|
38
|
+
after_films = cinema.films_after_time(time_s)
|
39
|
+
# comparison_time is an hour earlier than specified time
|
40
|
+
comparison_time = (time - AN_HOUR).to_s[HOUR_MIN]
|
41
|
+
day_films.each do |film, date_times|
|
42
|
+
date_times.each do |date, show_times|
|
43
|
+
if after_films[film].nil?
|
44
|
+
# If empty, all show times must be less than comparison time
|
45
|
+
show_times.each do |show_time|
|
46
|
+
show_time.must_be :<, comparison_time
|
47
|
+
end
|
48
|
+
else
|
49
|
+
after_show_times = after_films[film][date]
|
50
|
+
after_show_times.each do |ast|
|
51
|
+
# On day show times must include after request show times
|
52
|
+
show_times.must_include ast
|
53
|
+
# After show times must be greater than comparison time
|
54
|
+
if (ast < comparison_time) &&
|
55
|
+
(MIDNIGHT.include? ast[HOUR_PART])
|
56
|
+
# Movies airing from midnight onwards are group with past day
|
57
|
+
ast[HOUR_PART] = "#{ast[HOUR_PART].to_i + ADD_24}"
|
58
|
+
end
|
59
|
+
ast.must_be :>=, comparison_time
|
60
|
+
end
|
61
|
+
show_times -= after_films[film][date]
|
62
|
+
# Any show time not returned must be less than comparison time
|
63
|
+
show_times.each do |show_time|
|
64
|
+
show_time.must_be :<, comparison_time
|
65
|
+
end
|
66
|
+
end; end; end; end; end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
29
70
|
# describe 'Outside of 1 and 14 must fail' do
|
30
71
|
# FAIL_SITES.each do |site|
|
31
72
|
# it "must fail for #{site}" do
|
@@ -1,68 +1,131 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
2
|
+
國賓影城@新竹環球世博店:
|
3
|
+
SCOUTS GUIDE TO THE ZOMBIE APOCALYPSE:
|
4
|
+
2015/11/14:
|
5
|
+
- '10:30'
|
6
|
+
- '12:20'
|
7
|
+
- '14:10'
|
8
|
+
- '16:00'
|
9
|
+
- '17:50'
|
10
|
+
- '19:40'
|
11
|
+
- '21:30'
|
12
|
+
2015/11/15:
|
13
|
+
- '10:30'
|
14
|
+
- '12:20'
|
15
|
+
- '14:10'
|
16
|
+
- '16:00'
|
17
|
+
- '17:50'
|
18
|
+
- '19:40'
|
19
|
+
- '21:30'
|
20
|
+
2015/11/16:
|
21
|
+
- '12:00'
|
22
|
+
- '13:50'
|
23
|
+
- '15:40'
|
24
|
+
- '17:30'
|
25
|
+
- '19:20'
|
26
|
+
- '21:10'
|
27
|
+
2015/11/17:
|
28
|
+
- '12:00'
|
29
|
+
- '13:50'
|
30
|
+
- '15:40'
|
31
|
+
- '17:30'
|
32
|
+
- '19:20'
|
33
|
+
- '21:10'
|
34
|
+
2015/11/18:
|
35
|
+
- '12:00'
|
36
|
+
- '13:50'
|
37
|
+
- '15:40'
|
38
|
+
- '17:30'
|
39
|
+
- '19:20'
|
40
|
+
- '21:10'
|
41
|
+
2015/11/19:
|
42
|
+
- '12:00'
|
43
|
+
- '13:50'
|
44
|
+
- '15:40'
|
45
|
+
- '17:30'
|
46
|
+
- '19:20'
|
47
|
+
- '21:10'
|
48
|
+
Spectre:
|
49
|
+
2015/11/14:
|
50
|
+
- '10:20'
|
51
|
+
- '11:30'
|
52
|
+
- '13:00'
|
53
|
+
- '14:10'
|
54
|
+
- '16:40'
|
55
|
+
- '17:40'
|
56
|
+
- '18:50'
|
57
|
+
- '20:20'
|
58
|
+
- '21:30'
|
59
|
+
2015/11/15:
|
60
|
+
- '10:20'
|
61
|
+
- '11:30'
|
62
|
+
- '13:00'
|
63
|
+
- '14:10'
|
64
|
+
- '16:40'
|
65
|
+
- '17:40'
|
66
|
+
- '18:50'
|
67
|
+
- '20:20'
|
68
|
+
- '21:30'
|
69
|
+
2015/11/16:
|
70
|
+
- '11:30'
|
71
|
+
- '12:30'
|
72
|
+
- '14:10'
|
73
|
+
- '15:10'
|
74
|
+
- '16:20'
|
75
|
+
- '17:50'
|
76
|
+
- '18:50'
|
77
|
+
- '20:30'
|
78
|
+
- '21:30'
|
79
|
+
2015/11/17:
|
80
|
+
- '11:30'
|
81
|
+
- '12:30'
|
82
|
+
- '14:10'
|
83
|
+
- '15:10'
|
84
|
+
- '16:10'
|
85
|
+
- '17:50'
|
86
|
+
- '18:50'
|
87
|
+
- '20:30'
|
88
|
+
- '21:30'
|
89
|
+
2015/11/18:
|
90
|
+
- '11:30'
|
91
|
+
- '12:30'
|
92
|
+
- '14:10'
|
93
|
+
- '15:10'
|
94
|
+
- '16:20'
|
95
|
+
- '17:50'
|
96
|
+
- '18:50'
|
97
|
+
- '20:30'
|
98
|
+
- '21:30'
|
99
|
+
2015/11/19:
|
100
|
+
- '11:30'
|
101
|
+
- '12:30'
|
102
|
+
- '14:10'
|
103
|
+
- '15:10'
|
104
|
+
- '16:20'
|
105
|
+
- '17:50'
|
106
|
+
- '18:50'
|
107
|
+
- '20:30'
|
108
|
+
- '21:30'
|
109
|
+
The Little Prince:
|
110
|
+
2015/11/14:
|
111
|
+
- '10:40'
|
112
|
+
- '12:40'
|
113
|
+
- '15:40'
|
114
|
+
- '16:50'
|
115
|
+
2015/11/15:
|
116
|
+
- '10:40'
|
117
|
+
- '12:40'
|
118
|
+
- '15:40'
|
119
|
+
- '16:50'
|
120
|
+
2015/11/16:
|
121
|
+
- '12:20'
|
122
|
+
- '16:50'
|
123
|
+
2015/11/17:
|
124
|
+
- '12:10'
|
125
|
+
- '16:50'
|
126
|
+
2015/11/18:
|
127
|
+
- '12:20'
|
128
|
+
- '16:50'
|
129
|
+
2015/11/19:
|
130
|
+
- '12:20'
|
131
|
+
- '16:50'
|