cinebase 5.2.0 → 5.4.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: 6e2e7e8c5976a431db0d55f18a831e89e2dda1590dcac508f959e17d06cbdeb3
4
- data.tar.gz: 20a8dd91bca32d0b31ccd45e1c6d7f2940c0caaa0e0ab184a44a64f3eecaaaea
3
+ metadata.gz: 9cf2b85c2edc9824535b2304c6a138c9fcb1f741514729c68f997bd11691b3cf
4
+ data.tar.gz: 617e4142d0f55a1fa36b0c01accf4c4c620ac9816f6dc0f2ddde3e247fb6c16e
5
5
  SHA512:
6
- metadata.gz: 400b26c276c60dfc217148f80d85a216a641731f56cacdce68f2b940454b850fc1d142f2055371f1ad54108e228b85d324c0458247dd66e4404f750622c03ab8
7
- data.tar.gz: 978a46e47f5a6e004b0f0d1b79dbdb01d8d6c99db800c499db596bb9cf64b336b189c54614241ae93112a7a902fd5e7fe21b757bbbafdef102b35426a871fbad
6
+ metadata.gz: 8d2317b3bbf779296fde7e95e2982304cf6a23a2710e271539c1bfa2c2f107b5c77b5c07187c31ff85a59bce37b3cb2efcac1f60b8a276ad0c9009de1e9d1e19
7
+ data.tar.gz: b8f2b58778e8dafab5c9811fabd6cba08f24b6b9f5f9c20814d9bc2252e44fc6c502a8fb6901a029ac36066cb392d610f1d6938da6db0a73b10d99a9d059707a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
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.4.0] - 2026-10-22
6
+ ### Added
7
+ - `Vista::Client` accepts `region_code: nil` and then sends no `Connect-Region-Code` header, for chains such as Picturehouse whose API rejects every region code
8
+ - `COMMON_REMOVE` strips any `+ ... Q&A` or `+ ... Q+A` add-on, `+ Discussion`, `(35mm)`, `(70mm)` and a `4K` marker
9
+ - `Met Opera Encore 2026-27:` titles standardise like other Met Opera seasons
10
+ - `CFF:` (Cambridge Film Festival) title prefixes are festivals
11
+
12
+ ## [5.3.0] - 2026-10-22
13
+ ### Added
14
+ - `Performance#film_year` with an optional `film_year:` option, and `TitleSanitizer.film_year` reading a trailing `(1996)` from a title
15
+ - `COMMON_REMOVE` strips that year, `(Re-release)` and Lithuanian versions
16
+ - `Horror Season` title prefixes are festivals, so `Horror Season 2026 From Dusk Till Dawn (1996)` becomes `From Dusk Till Dawn`, year 1996, in the Horror Season 2026
17
+
18
+ ### Fixed
19
+ - Indentation of tests added in 5.2.0
20
+
5
21
  ## [5.2.0] - 2026-10-22
6
22
  ### Added
7
23
  - `Performance#festival`, `#language` and `#subtitled?`, with optional `festival:` and `language:` options
data/README.md CHANGED
@@ -45,7 +45,7 @@ module CinemaChainName
45
45
  def self.at(cinema_id)
46
46
  # parse webpages or apis to get performances for a cinema, built with
47
47
  # booking_url:, cinema_id:, cinema_name:, dimension:, festival:,
48
- # film_name:, language:, starting_at: and variant:
48
+ # film_name:, film_year:, language:, starting_at: and variant:
49
49
  end
50
50
  end
51
51
  end
@@ -85,6 +85,19 @@ Cinebase::Festival.from_title('UKJFF - From Cable Street To Brick Lane', year: 2
85
85
 
86
86
  `COMMON_REMOVE` strips the same prefixes from titles.
87
87
 
88
+ ### Film years
89
+
90
+ Titles often end with the film's year. `COMMON_REMOVE` strips it, and
91
+ `TitleSanitizer.film_year` reads it so it can be passed as `film_year:`:
92
+
93
+ ```ruby
94
+ Cinebase::TitleSanitizer.film_year('Street Fighter (2026)') #=> 2026
95
+ Cinebase::TitleSanitizer.film_year('Kung Fu Soccer (2026) (Dubbed)') #=> 2026
96
+ Cinebase::TitleSanitizer.film_year('Blade Runner 2049') #=> nil
97
+ ```
98
+
99
+ For a re-release this is the original year, which is what IMDb lists.
100
+
88
101
  ### Vista OCAPI chains
89
102
 
90
103
  Chains whose websites run on Vista share a client, guest token retrieval and
@@ -9,7 +9,9 @@ module Cinebase
9
9
  PREFIXES = [
10
10
  /\A(Cine-Excess) (20\d{2}): /,
11
11
  /\A(Cinemagic) (\d{4}) -/,
12
- /\A(UKJFF) -/
12
+ /\A(UKJFF) -/,
13
+ /\A(CFF): /,
14
+ /\A(Horror Season) (20\d{2}) /
13
15
  ].freeze
14
16
 
15
17
  # @param [String] title raw film title
@@ -9,6 +9,7 @@ module Cinebase
9
9
  attr_reader :cinema_name
10
10
  attr_reader :festival
11
11
  attr_reader :film_name
12
+ attr_reader :film_year
12
13
  attr_reader :language
13
14
 
14
15
  def initialize(options)
@@ -18,6 +19,7 @@ module Cinebase
18
19
  @dimension = options.fetch(:dimension, '2d')
19
20
  @festival = options.fetch(:festival, nil)
20
21
  @film_name = options.fetch(:film_name)
22
+ @film_year = options.fetch(:film_year, nil)
21
23
  @language = options.fetch(:language, nil)
22
24
  @time = options.fetch(:starting_at)
23
25
  @variant = options.fetch(:variant, [])
@@ -32,8 +32,12 @@ module Cinebase
32
32
  # Rules every chain can share; subclasses opt in after their own patterns,
33
33
  # e.g. `[...] + COMMON_REMOVE` in #remove
34
34
  class TitleSanitizer
35
- LANGUAGES = %w(Arabic Cantonese French Hindi Kannada Korean Malayalam
36
- Mandarin Marathi Polish Punjabi Tamil Telugu Turkish).freeze
35
+ LANGUAGES = %w(Arabic Cantonese French Hindi Kannada Korean Lithuanian
36
+ Malayalam Mandarin Marathi Polish Punjabi Tamil Telugu
37
+ Turkish).freeze
38
+
39
+ # A trailing "(1996)", allowing other bracketed markers after it
40
+ FILM_YEAR = /\s*\((1[89]\d{2}|20\d{2})\)(?=(?:\s*\([^)]*\))*\s*\z)/
37
41
 
38
42
  COMMON_REMOVE = [
39
43
  *Festival::PREFIXES, # festival prefix
@@ -41,14 +45,25 @@ module Cinebase
41
45
  /\((#{LANGUAGES.join('|')})\)/i, # language version
42
46
  /\((Dubbed|Subbed|English Dub|[^)]*subtitles)\)/i, # dub or subtitle version
43
47
  /\(\d+(st|nd|rd|th) Anniversary\)/i, # anniversary re-release
44
- /\s*\+\s*(In-Person )?Q&A\z/i, # Q&A add-on
48
+ /\(Re-release\)/i, # re-release
49
+ FILM_YEAR, # film year, see .film_year
50
+ /\s*\+\s*(?:[\w-]+\s+)*Q(?:&|\+)A\z/i, # Q&A add-on
51
+ /\s*\+\s*Discussion\z/i, # discussion add-on
52
+ /\s*\((35|70)mm\)/i, # film gauge
53
+ /\s+4K\b/, # 4K restoration
45
54
  /:\s*Encore\z/i, # encore
46
55
  /\bsing-?a-?long\z/i, # singalong
47
56
  'amp;' # html ampersands
48
57
  ].freeze
49
58
 
59
+ # @param [String] title raw film title
60
+ # @return [Integer, nil] the film's year from a trailing "(1996)"
61
+ def self.film_year(title)
62
+ title[FILM_YEAR, 1]&.to_i
63
+ end
64
+
50
65
  COMMON_REPLACE = {
51
- /Met Opera 20\d{2}-\d{2}: (.*)/ => 'Met Opera: ',
66
+ /Met Opera (?:Encore )?20\d{2}-\d{2}: (.*)/ => 'Met Opera: ',
52
67
  /RBO (?:Cinema Season )?20\d{2}-\d{2}: (.*)/ => 'Royal Ballet and Opera: ',
53
68
  /WORLD TOUR(.*)/ => 'World Tour'
54
69
  }.freeze
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Cinebase version
4
4
  module Cinebase
5
- VERSION = '5.2.0'
5
+ VERSION = '5.4.0'
6
6
  end
@@ -8,7 +8,8 @@ module Cinebase
8
8
  # Makes guest-token GET requests to a chain's OCAPI
9
9
  class Client
10
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'
11
+ # @param [String, nil] region_code Connect-Region-Code header, e.g. 'UK'
12
+ # or 'GB'; nil for chains whose API rejects every region code
12
13
  # @param [String, nil] token raw guest JWT, without the "Bearer " prefix
13
14
  def initialize(base_url:, region_code:, token:)
14
15
  @base_url = base_url
@@ -44,7 +45,7 @@ module Cinebase
44
45
  uri.query = URI.encode_www_form(query) unless query.empty?
45
46
  request = Net::HTTP::Get.new(uri)
46
47
  request['Authorization'] = "Bearer #{@token}"
47
- request['Connect-Region-Code'] = @region_code
48
+ request['Connect-Region-Code'] = @region_code if @region_code
48
49
  request['Accept'] = 'application/json'
49
50
  Net::HTTP.start(uri.host, uri.port, use_ssl: true, open_timeout: 10, read_timeout: 30) do |http|
50
51
  http.request(request)
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.2.0
4
+ version: 5.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Croll