cinebase 5.1.0 → 5.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8eeea7aa51f9e7044878fb0d225f9512f18aa2d261375da3bc411a380c7287c
4
- data.tar.gz: 053420412dbdf2206b92f877712e2eb2e75831af50c65fcdf0a2a6a4ddfbf79b
3
+ metadata.gz: 6e2e7e8c5976a431db0d55f18a831e89e2dda1590dcac508f959e17d06cbdeb3
4
+ data.tar.gz: 20a8dd91bca32d0b31ccd45e1c6d7f2940c0caaa0e0ab184a44a64f3eecaaaea
5
5
  SHA512:
6
- metadata.gz: d44ee69d99e2ebe12581a709b8b7b82d68eb6d8e948d891d28fc901b770f8690e2c646c15cb52dc794641e5ba68c519cf2ab75f0745ea9e9e6b9fd5aa73a8523
7
- data.tar.gz: bbdedfd238c991cf8520d1fa7830ebf663e7ddf2a142a6effef71886b6f9dad886023e1f971d8ff8844d819c8b66366dde7c038d5be846ab5732a15a13712131
6
+ metadata.gz: 400b26c276c60dfc217148f80d85a216a641731f56cacdce68f2b940454b850fc1d142f2055371f1ad54108e228b85d324c0458247dd66e4404f750622c03ab8
7
+ data.tar.gz: 978a46e47f5a6e004b0f0d1b79dbdb01d8d6c99db800c499db596bb9cf64b336b189c54614241ae93112a7a902fd5e7fe21b757bbbafdef102b35426a871fbad
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- ruby-version: ['3.3', '3.4']
14
+ ruby-version: ['3.3', '3.4', '4.0']
15
15
 
16
16
  steps:
17
17
  - uses: actions/checkout@v4
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby 3.4.7
1
+ 3.4.7
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [5.2.0] - 2026-10-22
6
+ ### Added
7
+ - `Performance#festival`, `#language` and `#subtitled?`, with optional `festival:` and `language:` options
8
+ - `Cinebase::Festival` value object (`name`, `year`) and `Festival.from_title`
9
+ - `TitleSanitizer::COMMON_REMOVE` and `COMMON_REPLACE`: opt-in rules for dub and subtitle versions, language versions, anniversaries, Q&A add-ons, encores, sing-alongs, festival prefixes, opera and ballet seasons, and `WORLD TOUR` capitals
10
+ - `cinebase/vista`, loaded only on request, for chains on Vista OCAPI: `Vista::Client`, a `Vista::GuestToken` template and `Vista::PackageTask` for platform gems bundling curl-impersonate
11
+ - CI on Ruby 4.0
12
+
5
13
  ## [5.1.0] - 2025-10-31
6
14
  ### Changed
7
15
  - Converted all test files from minitest spec syntax to vanilla minitest syntax
data/README.md CHANGED
@@ -1,9 +1,6 @@
1
1
  # Cinebase
2
2
 
3
3
  [![](https://img.shields.io/gem/v/cinebase.svg)](http://rubygems.org/gems/cinebase)
4
- [![](https://img.shields.io/travis/andycroll/cinebase.svg)](https://travis-ci.org/andycroll/cinebase)
5
- [![](https://img.shields.io/codeclimate/github/andycroll/cinebase.svg)](https://codeclimate.com/github/andycroll/cinebase)
6
- [![](https://img.shields.io/codeclimate/coverage/github/andycroll/cinebase.svg)](https://codeclimate.com/github/andycroll/cinebase/coverage)
7
4
  ![](https://img.shields.io/github/license/andycroll/cinebase.svg)
8
5
 
9
6
  A basic interface for a series of cinema gems.
@@ -44,9 +41,11 @@ module CinemaChainName
44
41
  end
45
42
 
46
43
  module CinemaChainName
47
- class Screening < Cinebase::Screening
44
+ class Performance < Cinebase::Performance
48
45
  def self.at(cinema_id)
49
- # parse webpages or apis to get screenings for a cinema
46
+ # parse webpages or apis to get performances for a cinema, built with
47
+ # booking_url:, cinema_id:, cinema_name:, dimension:, festival:,
48
+ # film_name:, language:, starting_at: and variant:
50
49
  end
51
50
  end
52
51
  end
@@ -56,18 +55,79 @@ module CinemaChainName
56
55
  class TitleSanitizer < Cinebase::TitleSanitizer
57
56
  private
58
57
 
58
+ # Chain patterns first, so markers like trailing sing-alongs are at the
59
+ # end of the title by the time the common rules run
59
60
  def remove
60
- # []
61
+ [] + COMMON_REMOVE # chain-specific patterns, then the common ones
61
62
  end
62
63
 
63
64
  def replace
64
- # { core title regex => replacement text }
65
+ {}.merge(COMMON_REPLACE) # { core title regex => replacement text }
65
66
  end
66
67
  end
67
68
  end
68
69
  end
69
70
  ```
70
71
 
72
+ ### Festivals
73
+
74
+ A festival is an annual event, so `Cinebase::Festival` holds the name and the
75
+ edition year. Pass it to a performance as `festival:`.
76
+
77
+ ```ruby
78
+ Cinebase::Festival.from_title('Cine-Excess 2026: Scum Of The Earth', year: 2026)
79
+ #=> #<data Cinebase::Festival name="Cine-Excess", year=2026>
80
+
81
+ # No year in the title, so the screening's year is the edition
82
+ Cinebase::Festival.from_title('UKJFF - From Cable Street To Brick Lane', year: 2026)
83
+ #=> #<data Cinebase::Festival name="UKJFF", year=2026>
84
+ ```
85
+
86
+ `COMMON_REMOVE` strips the same prefixes from titles.
87
+
88
+ ### Vista OCAPI chains
89
+
90
+ Chains whose websites run on Vista share a client, guest token retrieval and
91
+ packaging. These are not loaded by `require 'cinebase'`:
92
+
93
+ ```ruby
94
+ require 'cinebase/vista'
95
+
96
+ client = Cinebase::Vista::Client.new(
97
+ base_url: 'https://vwc.odeon.co.uk/WSVistaWebClient/ocapi/v1/',
98
+ region_code: 'UK',
99
+ token: guest_jwt
100
+ )
101
+ client.get('sites')
102
+
103
+ module CinemaChainName
104
+ class GuestToken < Cinebase::Vista::GuestToken
105
+ PAGE_URL = 'https://www.example.co.uk/page-with-the-token/'.freeze
106
+
107
+ private
108
+
109
+ def bundled_curl
110
+ File.expand_path('../../vendor/curl-impersonate/bin/curl-impersonate', __dir__)
111
+ end
112
+
113
+ def extract_token(html)
114
+ # return the guest JWT from the page
115
+ end
116
+ end
117
+ end
118
+ ```
119
+
120
+ `GuestToken#fetch` runs `curl-impersonate` with a Chrome profile, checks the
121
+ token's declared expiry and raises `Cinebase::Vista::AuthenticationError` when
122
+ it cannot get a current token. To ship curl-impersonate inside platform gems,
123
+ add this to the chain gem's Rakefile:
124
+
125
+ ```ruby
126
+ require 'cinebase/vista/package_task'
127
+ Cinebase::Vista::PackageTask.new('chain_name.gemspec')
128
+ # rake 'package:native[arm64-darwin]' or rake package:all
129
+ ```
130
+
71
131
  ## Contributing
72
132
 
73
133
  1. [Fork it](https://github.com/andycroll/cinebase/fork)
data/cinebase.gemspec CHANGED
@@ -18,10 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ['lib']
20
20
 
21
+ spec.add_development_dependency 'base64'
21
22
  spec.add_development_dependency 'bundler', '>= 2.0'
22
23
  spec.add_development_dependency 'minitest-reporters'
23
24
  spec.add_development_dependency 'rake', '>= 13.0'
24
25
  spec.add_development_dependency 'simplecov', '~> 0.22'
26
+ spec.add_development_dependency 'webmock'
25
27
 
26
28
  spec.add_runtime_dependency 'tzinfo'
27
29
  spec.add_runtime_dependency 'tzinfo-data'
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cinebase
4
+ Festival = Data.define(:name, :year)
5
+
6
+ # An annual festival edition a film is screened in
7
+ class Festival
8
+ # Title prefixes naming a festival: the name, then the year when given
9
+ PREFIXES = [
10
+ /\A(Cine-Excess) (20\d{2}): /,
11
+ /\A(Cinemagic) (\d{4}) -/,
12
+ /\A(UKJFF) -/
13
+ ].freeze
14
+
15
+ # @param [String] title raw film title
16
+ # @param [Integer] year the edition when the title gives none, usually the
17
+ # screening's year
18
+ # @return [Cinebase::Festival, nil]
19
+ def self.from_title(title, year:)
20
+ PREFIXES.each do |prefix|
21
+ match = title.match(prefix)
22
+ return new(name: match[1], year: Integer(match[2] || year)) if match
23
+ end
24
+ nil
25
+ end
26
+ end
27
+ end
@@ -7,14 +7,18 @@ module Cinebase
7
7
  attr_reader :dimension
8
8
  attr_reader :cinema_id
9
9
  attr_reader :cinema_name
10
+ attr_reader :festival
10
11
  attr_reader :film_name
12
+ attr_reader :language
11
13
 
12
14
  def initialize(options)
13
15
  @booking_url = options.fetch(:booking_url, nil)
14
16
  @cinema_name = options.fetch(:cinema_name)
15
17
  @cinema_id = options.fetch(:cinema_id)
16
18
  @dimension = options.fetch(:dimension, '2d')
19
+ @festival = options.fetch(:festival, nil)
17
20
  @film_name = options.fetch(:film_name)
21
+ @language = options.fetch(:language, nil)
18
22
  @time = options.fetch(:starting_at)
19
23
  @variant = options.fetch(:variant, [])
20
24
  end
@@ -41,5 +45,10 @@ module Cinebase
41
45
  @variant = @variant.split(' ') if @variant.is_a?(String)
42
46
  @variant.map(&:downcase).sort.uniq
43
47
  end
48
+
49
+ # English subtitles or open captions
50
+ def subtitled?
51
+ variant.include?('subtitled')
52
+ end
44
53
  end
45
54
  end
@@ -27,3 +27,30 @@ module Cinebase
27
27
  end
28
28
  end
29
29
  end
30
+
31
+ module Cinebase
32
+ # Rules every chain can share; subclasses opt in after their own patterns,
33
+ # e.g. `[...] + COMMON_REMOVE` in #remove
34
+ class TitleSanitizer
35
+ LANGUAGES = %w(Arabic Cantonese French Hindi Kannada Korean Malayalam
36
+ Mandarin Marathi Polish Punjabi Tamil Telugu Turkish).freeze
37
+
38
+ COMMON_REMOVE = [
39
+ *Festival::PREFIXES, # festival prefix
40
+ /\s+[23]d\b/i, # dimension
41
+ /\((#{LANGUAGES.join('|')})\)/i, # language version
42
+ /\((Dubbed|Subbed|English Dub|[^)]*subtitles)\)/i, # dub or subtitle version
43
+ /\(\d+(st|nd|rd|th) Anniversary\)/i, # anniversary re-release
44
+ /\s*\+\s*(In-Person )?Q&A\z/i, # Q&A add-on
45
+ /:\s*Encore\z/i, # encore
46
+ /\bsing-?a-?long\z/i, # singalong
47
+ 'amp;' # html ampersands
48
+ ].freeze
49
+
50
+ COMMON_REPLACE = {
51
+ /Met Opera 20\d{2}-\d{2}: (.*)/ => 'Met Opera: ',
52
+ /RBO (?:Cinema Season )?20\d{2}-\d{2}: (.*)/ => 'Royal Ballet and Opera: ',
53
+ /WORLD TOUR(.*)/ => 'World Tour'
54
+ }.freeze
55
+ end
56
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Cinebase version
4
4
  module Cinebase
5
- VERSION = '5.1.0'
5
+ VERSION = '5.2.0'
6
6
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+
6
+ module Cinebase
7
+ module Vista
8
+ # Makes guest-token GET requests to a chain's OCAPI
9
+ class Client
10
+ # @param [String] base_url e.g. 'https://vwc.odeon.co.uk/WSVistaWebClient/ocapi/v1/'
11
+ # @param [String] region_code Connect-Region-Code header, e.g. 'UK' or 'GB'
12
+ # @param [String, nil] token raw guest JWT, without the "Bearer " prefix
13
+ def initialize(base_url:, region_code:, token:)
14
+ @base_url = base_url
15
+ @region_code = region_code
16
+ @token = token
17
+ end
18
+
19
+ # @param [String] path relative to the base URL
20
+ # @param [Hash] query parameters; Array values repeat the key
21
+ # @return [Hash] parsed JSON
22
+ # @raise [Cinebase::Vista::AuthenticationError] missing or rejected token
23
+ def get(path, query = {})
24
+ if !@token.is_a?(String) || @token.strip.empty?
25
+ raise AuthenticationError, 'Set a current guest token before fetching data'
26
+ end
27
+
28
+ response = request(path, query)
29
+ case response
30
+ when Net::HTTPSuccess
31
+ JSON.parse(response.body)
32
+ when Net::HTTPUnauthorized
33
+ raise AuthenticationError, 'Vista rejected the guest token; supply a fresh one'
34
+ else
35
+ # Omit response bodies and never redirect credentials to another host.
36
+ raise "Vista HTTP error #{response.code}"
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def request(path, query)
43
+ uri = URI(@base_url + path)
44
+ uri.query = URI.encode_www_form(query) unless query.empty?
45
+ request = Net::HTTP::Get.new(uri)
46
+ request['Authorization'] = "Bearer #{@token}"
47
+ request['Connect-Region-Code'] = @region_code
48
+ request['Accept'] = 'application/json'
49
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true, open_timeout: 10, read_timeout: 30) do |http|
50
+ http.request(request)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'open3'
5
+
6
+ module Cinebase
7
+ module Vista
8
+ # Retrieves a chain website's public guest token with curl-impersonate,
9
+ # without running a browser. Subclasses set PAGE_URL and implement
10
+ # #extract_token(html) and #bundled_curl.
11
+ class GuestToken
12
+ # @param [String, nil] curl curl-impersonate executable; defaults to the
13
+ # one bundled in the chain gem, then the one on PATH
14
+ def initialize(curl: nil)
15
+ @curl = curl || default_curl
16
+ end
17
+
18
+ # @return [String] the guest JWT
19
+ # @raise [Cinebase::Vista::AuthenticationError]
20
+ def fetch
21
+ token = extract_token(request_page)
22
+ unless token.is_a?(String) && !token.empty?
23
+ raise AuthenticationError, 'Guest token is missing from the page'
24
+ end
25
+ validate_expiry!(token)
26
+ token
27
+ rescue JSON::ParserError, ArgumentError, IndexError, TypeError, NoMethodError
28
+ raise AuthenticationError, 'Guest token page data is missing or invalid', cause: nil
29
+ end
30
+
31
+ private
32
+
33
+ # HTTP statuses whose page still carries the token
34
+ def accepted_statuses
35
+ %w[200]
36
+ end
37
+
38
+ def bundled_curl
39
+ nil
40
+ end
41
+
42
+ def default_curl
43
+ bundled_curl && File.executable?(bundled_curl) ? bundled_curl : 'curl-impersonate'
44
+ end
45
+
46
+ def curl_command
47
+ [@curl, '--disable', '--impersonate', 'chrome150',
48
+ '--compressed', '--silent', '--show-error',
49
+ '--connect-timeout', '10', '--max-time', '30',
50
+ '--write-out', "\n%{http_code}", self.class::PAGE_URL]
51
+ end
52
+
53
+ def request_page
54
+ output, _stderr, result = Open3.capture3(*curl_command)
55
+ unless result.success?
56
+ raise AuthenticationError, "Guest token request failed (curl exit #{result.exitstatus})"
57
+ end
58
+
59
+ html, _, status = output.rpartition("\n")
60
+ unless accepted_statuses.include?(status)
61
+ raise AuthenticationError, "Guest token page returned HTTP #{status}"
62
+ end
63
+ html
64
+ rescue Errno::ENOENT
65
+ raise AuthenticationError, 'Install curl-impersonate or pass its executable path with curl:'
66
+ end
67
+
68
+ def validate_expiry!(token)
69
+ payload = token.split('.').fetch(1).tr('-_', '+/').unpack1('m')
70
+ claims = JSON.parse(payload)
71
+ if Integer(claims.fetch('exp')) <= Time.now.to_i
72
+ raise AuthenticationError, 'Guest token supplied by the page has expired'
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest'
4
+ require 'fileutils'
5
+ require 'rake'
6
+ require 'rubygems/package'
7
+ require 'tmpdir'
8
+ require 'zlib'
9
+
10
+ module Cinebase
11
+ module Vista
12
+ # Defines package:native[platform] and package:all, which build platform
13
+ # gems that bundle curl-impersonate for GuestToken. In a chain gem's
14
+ # Rakefile: `Cinebase::Vista::PackageTask.new('odeon_uk.gemspec')`
15
+ class PackageTask
16
+ include Rake::DSL
17
+
18
+ VERSION = '2.2.3'
19
+
20
+ # Platform => [upstream asset target, SHA-256 of the v2.2.3 release asset]
21
+ RELEASES = {
22
+ 'x86_64-linux-gnu' => ['x86_64-linux-gnu', 'ca7c8aae49e33260d3a2400db16c7737aaf04692d606a843502056b42990f989'],
23
+ 'aarch64-linux-gnu' => ['aarch64-linux-gnu', '5e71795b971f32be8f3d7785895f4dceb232f04414f5a067db266432a5b08657'],
24
+ 'arm64-darwin' => ['arm64-macos', '2569f4139460fcb301484d37938de91b1c220efd15487ee22a9db554262062fe'],
25
+ 'x86_64-darwin' => ['x86_64-macos', '4686806d59abea93866a917c3025a049ef3d7a3240de742ad66bd1a4d9890dc7']
26
+ }.freeze
27
+
28
+ # @param [String] gemspec path to the chain gem's gemspec
29
+ # @param [String] root the chain gem's root directory
30
+ def initialize(gemspec, root: Dir.pwd)
31
+ @gemspec = gemspec
32
+ @root = root
33
+ define
34
+ end
35
+
36
+ private
37
+
38
+ def define
39
+ namespace :package do
40
+ desc "Build a gem with bundled curl-impersonate #{VERSION} for the given platform"
41
+ task :native, [:platform] do |_task, args|
42
+ build(args.fetch(:platform))
43
+ end
44
+
45
+ desc 'Build all supported platform gems with bundled curl-impersonate'
46
+ task :all do
47
+ RELEASES.each_key { |platform| build(platform) }
48
+ end
49
+ end
50
+ end
51
+
52
+ def build(platform)
53
+ target, digest = RELEASES.fetch(platform)
54
+ asset = "curl-impersonate-v#{VERSION}.#{target}.tar.gz"
55
+ url = "https://github.com/lexiforest/curl-impersonate/releases/download/v#{VERSION}/#{asset}"
56
+ archive = File.join(@root, 'pkg', 'downloads', asset)
57
+ download(url, archive)
58
+ abort "SHA-256 mismatch for #{archive}; delete it and retry" unless Digest::SHA256.file(archive).hexdigest == digest
59
+
60
+ spec = Gem::Specification.load(File.join(@root, @gemspec)).dup
61
+ Dir.mktmpdir('vista-package') do |stage|
62
+ spec.files.each do |file|
63
+ destination = File.join(stage, file)
64
+ FileUtils.mkdir_p(File.dirname(destination))
65
+ FileUtils.cp(File.join(@root, file), destination)
66
+ end
67
+ vendor(archive, File.join(stage, 'vendor', 'curl-impersonate'), url, digest)
68
+
69
+ Dir.chdir(stage) do
70
+ spec.platform = Gem::Platform.new(platform)
71
+ spec.files += Dir.glob('vendor/**/*').select { |file| File.file?(file) }
72
+ Gem::Package.build(spec, false, false, File.join(@root, 'pkg', spec.file_name))
73
+ end
74
+ end
75
+ end
76
+
77
+ def download(url, archive)
78
+ FileUtils.mkdir_p(File.dirname(archive))
79
+ sh 'curl', '--fail', '--location', '--retry', '3', '--output', archive, url unless File.exist?(archive)
80
+ end
81
+
82
+ def vendor(archive, vendor, url, digest)
83
+ Zlib::GzipReader.open(archive) do |gzip|
84
+ Gem::Package::TarReader.new(gzip) do |tar|
85
+ tar.each do |entry|
86
+ next unless entry.file?
87
+
88
+ relative = vendor_path(entry.full_name)
89
+ next unless relative
90
+
91
+ destination = File.join(vendor, relative)
92
+ FileUtils.mkdir_p(File.dirname(destination))
93
+ File.binwrite(destination, entry.read)
94
+ end
95
+ end
96
+ end
97
+ File.chmod(0o755, File.join(vendor, 'bin', 'curl-impersonate'))
98
+ File.write(File.join(vendor, 'SOURCE'), <<~SOURCE)
99
+ curl-impersonate #{VERSION}
100
+ Binary: #{url}
101
+ SHA-256: #{digest}
102
+ Source and build instructions: https://github.com/lexiforest/curl-impersonate/tree/v#{VERSION}
103
+ Redistribution notices: licenses/
104
+ SOURCE
105
+ end
106
+
107
+ def vendor_path(name)
108
+ if name == 'curl-impersonate'
109
+ 'bin/curl-impersonate'
110
+ elsif name.start_with?('LICENSE') && File.basename(name) == name
111
+ "licenses/#{name}"
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cinebase'
4
+
5
+ module Cinebase
6
+ # Shared support for chains whose sites run on Vista's OCAPI. Not loaded by
7
+ # `require 'cinebase'`; Vista-based gems `require 'cinebase/vista'`.
8
+ module Vista
9
+ class AuthenticationError < StandardError; end
10
+ end
11
+ end
12
+
13
+ require 'cinebase/vista/client'
14
+ require 'cinebase/vista/guest_token'
data/lib/cinebase.rb CHANGED
@@ -6,5 +6,6 @@ require 'tzinfo/data'
6
6
  require 'cinebase/version'
7
7
 
8
8
  require 'cinebase/cinema'
9
+ require 'cinebase/festival'
9
10
  require 'cinebase/performance'
10
11
  require 'cinebase/title_sanitizer'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cinebase
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Croll
@@ -9,6 +9,20 @@ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: bundler
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +79,20 @@ dependencies:
65
79
  - - "~>"
66
80
  - !ruby/object:Gem::Version
67
81
  version: '0.22'
82
+ - !ruby/object:Gem::Dependency
83
+ name: webmock
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
68
96
  - !ruby/object:Gem::Dependency
69
97
  name: tzinfo
70
98
  requirement: !ruby/object:Gem::Requirement
@@ -116,9 +144,14 @@ files:
116
144
  - cinebase.gemspec
117
145
  - lib/cinebase.rb
118
146
  - lib/cinebase/cinema.rb
147
+ - lib/cinebase/festival.rb
119
148
  - lib/cinebase/performance.rb
120
149
  - lib/cinebase/title_sanitizer.rb
121
150
  - lib/cinebase/version.rb
151
+ - lib/cinebase/vista.rb
152
+ - lib/cinebase/vista/client.rb
153
+ - lib/cinebase/vista/guest_token.rb
154
+ - lib/cinebase/vista/package_task.rb
122
155
  homepage: http://github.com/andycroll/cinebase
123
156
  licenses:
124
157
  - MIT