sesc 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f1af287b2d12a83b73203f0a0ac216916ff4345d2470e786d98d7fce0bdf5bda
4
+ data.tar.gz: 6d538626821c941ab3106a122d9ef77ffb20bd3f8599217f987eaace630f0dca
5
+ SHA512:
6
+ metadata.gz: 181ab6e77f3f557f6909ab7c51232bb90f28f77f5921f2cf8aba1bef5b0e2f3edc2393c52f284c88ada58fe36a0e518e6a6f733eb2a205b3969174bae0068830
7
+ data.tar.gz: c1c0e6afa349de3b839dbd4a17b481c901c8e671bf2066b05537f460518ab7663b3a9a58c208d6a1d7e76fc78b4ade72e1f37a2e243d282096aaf86f7a1e8cbd
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+
4
+ Style/BlockLength:
5
+ Exclude:
6
+ - sesc.gemspec
7
+ - spec/**/*.rb
8
+
9
+ Documentation:
10
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.0
data/Gemfile.lock ADDED
@@ -0,0 +1,103 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sesc (0.1.8)
5
+ nokogiri (~> 1.8.0, >= 1.8.0)
6
+ thor (~> 0.20.0, >= 0.20.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (5.2.0)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 0.7, < 2)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
16
+ addressable (2.5.2)
17
+ public_suffix (>= 2.0.2, < 4.0)
18
+ ast (2.4.0)
19
+ byebug (3.5.1)
20
+ columnize (~> 0.8)
21
+ debugger-linecache (~> 1.2)
22
+ slop (~> 3.6)
23
+ coderay (1.1.2)
24
+ colorize (0.8.1)
25
+ columnize (0.9.0)
26
+ concurrent-ruby (1.0.5)
27
+ crack (0.4.3)
28
+ safe_yaml (~> 1.0.0)
29
+ debugger-linecache (1.2.0)
30
+ diff-lcs (1.3)
31
+ factory_bot (4.8.2)
32
+ activesupport (>= 3.0.0)
33
+ hashdiff (0.3.7)
34
+ i18n (1.0.1)
35
+ concurrent-ruby (~> 1.0)
36
+ method_source (0.9.0)
37
+ mini_portile2 (2.3.0)
38
+ minitest (5.11.3)
39
+ nokogiri (1.8.2)
40
+ mini_portile2 (~> 2.3.0)
41
+ parallel (1.12.1)
42
+ parser (2.5.1.0)
43
+ ast (~> 2.4.0)
44
+ powerpack (0.1.1)
45
+ pry (0.11.3)
46
+ coderay (~> 1.1.0)
47
+ method_source (~> 0.9.0)
48
+ pry-byebug (3.0.1)
49
+ byebug (~> 3.4)
50
+ pry (~> 0.10)
51
+ public_suffix (3.0.2)
52
+ rainbow (2.2.2)
53
+ rake
54
+ rake (12.3.1)
55
+ rspec (3.7.0)
56
+ rspec-core (~> 3.7.0)
57
+ rspec-expectations (~> 3.7.0)
58
+ rspec-mocks (~> 3.7.0)
59
+ rspec-core (3.7.1)
60
+ rspec-support (~> 3.7.0)
61
+ rspec-expectations (3.7.0)
62
+ diff-lcs (>= 1.2.0, < 2.0)
63
+ rspec-support (~> 3.7.0)
64
+ rspec-mocks (3.7.0)
65
+ diff-lcs (>= 1.2.0, < 2.0)
66
+ rspec-support (~> 3.7.0)
67
+ rspec-support (3.7.1)
68
+ rubocop (0.51.0)
69
+ parallel (~> 1.10)
70
+ parser (>= 2.3.3.1, < 3.0)
71
+ powerpack (~> 0.1)
72
+ rainbow (>= 2.2.2, < 3.0)
73
+ ruby-progressbar (~> 1.7)
74
+ unicode-display_width (~> 1.0, >= 1.0.1)
75
+ ruby-progressbar (1.9.0)
76
+ safe_yaml (1.0.4)
77
+ slop (3.6.0)
78
+ thor (0.20.0)
79
+ thread_safe (0.3.6)
80
+ tzinfo (1.2.5)
81
+ thread_safe (~> 0.1)
82
+ unicode-display_width (1.3.2)
83
+ vcr (3.0.3)
84
+ webmock (3.3.0)
85
+ addressable (>= 2.3.6)
86
+ crack (>= 0.3.2)
87
+ hashdiff
88
+
89
+ PLATFORMS
90
+ ruby
91
+
92
+ DEPENDENCIES
93
+ colorize
94
+ factory_bot (~> 4.8.2, >= 4.8.2)
95
+ pry-byebug (~> 3.0.1, >= 3.0.1)
96
+ rspec (~> 3.7)
97
+ rubocop (~> 0.51.0, >= 0.51.0)
98
+ sesc!
99
+ vcr (~> 3.0, >= 3.0.0)
100
+ webmock (~> 3.1, >= 3.1.0)
101
+
102
+ BUNDLED WITH
103
+ 1.16.1
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 fernandopso
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # sesc
2
+
3
+ https://www.sescsp.org.br
4
+
5
+ ![sesc](https://user-images.githubusercontent.com/3316732/38907228-357d207e-4291-11e8-9f6a-3852c5f07161.gif)
6
+
7
+ ## Install
8
+
9
+ **Sesc** installation is standard for a Ruby gem:
10
+
11
+ ```sh
12
+ $ gem install sesc
13
+ ```
14
+
15
+ then
16
+
17
+ ```
18
+ $ sesc --help
19
+ ```
data/bin/sesc ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+ require 'sesc'
5
+
6
+ Sesc::Cli.new(ARGV).call
data/config.yml ADDED
@@ -0,0 +1,4 @@
1
+ base_url: 'https://www.sescsp.org.br'
2
+ events_path: '/programacao/ajax/homeView.action?atividades=&calendar_dates=&remove_dates='
3
+ number: '&maxResults=%s'
4
+ places: '&unities=%s'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Cities
5
+ class Sp
6
+ def initialize(html_response)
7
+ @html_response = html_response
8
+ end
9
+
10
+ def print_on_terminal
11
+ Sesc::Exporter::Events.print(events)
12
+ end
13
+
14
+ private
15
+
16
+ def events
17
+ Sesc::Parser::Sp::Events.new(@html_response).to_hash
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Cities
5
+ CITIES_FOLDER = '/lib/sesc/cities/'
6
+
7
+ def self.include?(city)
8
+ valids.include?(city.downcase)
9
+ end
10
+
11
+ def self.valids
12
+ Dir[cities_path + '*'].map do |b|
13
+ b.gsub(cities_path, '').gsub('.rb', '').downcase
14
+ end
15
+ end
16
+
17
+ def self.cities_path
18
+ Gem::Specification.find_by_name('sesc').gem_dir + CITIES_FOLDER
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Cli
5
+ module Filter
6
+ PLACES = {
7
+ 'Grande São Paulo' => [
8
+ ['24 de Maio', 36],
9
+ ['Belenzinho', 25],
10
+ ['Bom Retiro', 72],
11
+ ['Campo Limpo', 681],
12
+ ['Carmo', 1],
13
+ ['Centro de Pesquisa e Formação', 601],
14
+ ['CineSesc', 2],
15
+ ['Consolação', 3],
16
+ ['Florêncio de Abreu', 7],
17
+ ['Interlagos', 4],
18
+ ['Ipiranga', 5],
19
+ ['Itaquera', 6],
20
+ ['Osasco', 69],
21
+ ['Parque Dom Pedro II', 781],
22
+ ['Pinheiros', 10],
23
+ ['Pompeia', 11],
24
+ ['Santana', 38],
25
+ ['Santo Amaro', 26],
26
+ ['Santo André', 37],
27
+ ['São Caetano', 12],
28
+ ['Vila Mariana', 13]
29
+ ],
30
+ 'Interior e litoral' => [
31
+ ['Araraquara', 32],
32
+ ['Bauru', 14],
33
+ ['Bertioga', 15],
34
+ ['Birigui', 28],
35
+ ['Campinas', 16],
36
+ ['Catanduva', 17],
37
+ ['Jundiaí', 741],
38
+ ['Piracicaba', 18],
39
+ ['Presidente Prudente', 68],
40
+ ['Registro', 761],
41
+ ['Ribeirão Preto', 19],
42
+ ['Rio Preto', 22],
43
+ ['Santos', 20],
44
+ ['Sorocaba', 39],
45
+ ['São Carlos', 21],
46
+ ['São José dos Campos', 23],
47
+ ['Taubaté', 24]
48
+ ]
49
+ }.freeze
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Cli
5
+ module Options
6
+ DEFAULT = { city: 'sp', number: 5, places: '' }.freeze
7
+
8
+ COMMANDS_WITH_OPTIONS = {
9
+ city: ['-c', '--city'],
10
+ number: ['-n', '--number'],
11
+ places: ['-p', '--places']
12
+ }.freeze
13
+
14
+ COMMANDS_WITH_OPTIONS.each do |command, options|
15
+ define_method(command) do
16
+ index_for(options) ? args[index_for(options) + 1] : DEFAULT[command]
17
+ end
18
+ end
19
+
20
+ def help?
21
+ args.include?('-h') || args.include?('--help')
22
+ end
23
+
24
+ def places?
25
+ args.include?('places')
26
+ end
27
+
28
+ def index_for(values)
29
+ values.each { |v| return args.index(v) if args.index(v) }
30
+ nil
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/sesc/cli.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Cli
5
+ include Sesc::Cli::Options
6
+
7
+ attr_accessor :args
8
+
9
+ def initialize(args)
10
+ self.args = args
11
+ end
12
+
13
+ def call
14
+ return Sesc::Exporter::Help.print if help?
15
+ if places?
16
+ Sesc::Exporter::Places.print
17
+ elsif Sesc::Cities.include?(city)
18
+ Sesc.send(city, number, places)
19
+ else
20
+ Sesc::Exporter::Printer.new("Cidade #{city} não encontrada").terminal
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Config
5
+ class << self
6
+ ATTRIBUTES = %w[
7
+ base_url
8
+ events_path
9
+ number
10
+ places
11
+ ].freeze
12
+
13
+ ATTRIBUTES.each do |attr|
14
+ define_method(attr) do
15
+ file[attr]
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def file
22
+ @file ||= YAML.load_file(gem_path + '/config.yml')
23
+ end
24
+
25
+ def gem_path
26
+ Gem::Specification.find_by_name('sesc').gem_dir
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Crawler
5
+ def initialize(number, places)
6
+ @number = number
7
+ @places = places.to_s.split(',')
8
+ end
9
+
10
+ def get
11
+ request.body
12
+ end
13
+
14
+ private
15
+
16
+ def request
17
+ @request ||= Net::HTTP.post_form(uri_url_path, q: '')
18
+ end
19
+
20
+ def uri_url_path
21
+ URI(Sesc::Config.base_url + Sesc::Config.events_path + attrs)
22
+ end
23
+
24
+ def attrs
25
+ number + places.to_s
26
+ end
27
+
28
+ def number
29
+ Sesc::Config.number % @number
30
+ end
31
+
32
+ def places
33
+ @places.map { |p| Sesc::Config.places % from_to(p) }.join if @places.any?
34
+ end
35
+
36
+ def from_to(place)
37
+ Sesc::Cli::Filter::PLACES.values.flatten(1)[place.to_i - 1].last
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Exporter
5
+ class Events
6
+ class << self
7
+ ATTRIBUTES = %i[
8
+ title description place date price hours age_limit availability url
9
+ ].freeze
10
+
11
+ def print(sescs)
12
+ sescs.each do |sesc, events|
13
+ events.each do |event|
14
+ print_event_for(sesc, event) if availability?(event)
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def print_event_for(sesc, event)
22
+ title(event)
23
+ description(event)
24
+ place(sesc)
25
+ date(event)
26
+ price(event)
27
+ hours(event)
28
+ age_limit(event)
29
+ url(event)
30
+ end
31
+
32
+ def title(event)
33
+ pprint paint(event[:title], color: :blue), up: 1
34
+ end
35
+
36
+ def description(event)
37
+ pprint paint('Descrição: ') + paint(event[:description], yellow)
38
+ end
39
+
40
+ def place(sesc)
41
+ pprint paint('Local: ') + paint(sesc, yellow)
42
+ end
43
+
44
+ def date(event)
45
+ pprint paint('Datas: ') + paint(event[:date], yellow)
46
+ end
47
+
48
+ def price(event)
49
+ pprint paint('Preço: ') + paint(event[:price], yellow)
50
+ end
51
+
52
+ def availability?(event)
53
+ event[:availability] != 'Esgotado'
54
+ end
55
+
56
+ def age_limit(event)
57
+ pprint paint('Classificação: ') + paint(event[:age_limit], yellow)
58
+ end
59
+
60
+ def hours(event)
61
+ pprint paint('Horários: ') + paint(event[:hours], yellow)
62
+ end
63
+
64
+ def url(event)
65
+ pprint paint(Sesc::Config.base_url + event[:url])
66
+ end
67
+
68
+ def pprint(line, up: 0)
69
+ Sesc::Exporter::Printer.new(line, up: up).terminal
70
+ end
71
+
72
+ def paint(text, options = {})
73
+ Sesc::Exporter::Painter.new(text, options).default
74
+ end
75
+
76
+ def yellow
77
+ { color: :yellow }
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Exporter
5
+ class Help
6
+ DESCRIPTION = {
7
+ number: 'Quantidade de eventos a serem listados',
8
+ places: 'Unidades do sesc que podem serem filtradas'
9
+ }.freeze
10
+
11
+ FILTERS = {
12
+ places: 'Listar todos os SESC'
13
+ }.freeze
14
+
15
+ class << self
16
+ def print
17
+ header
18
+ options
19
+ help
20
+ descriptions
21
+ filters
22
+ true
23
+ end
24
+
25
+ def descriptions
26
+ DESCRIPTION.each do |command, description|
27
+ text = alias_for(command)
28
+ puts("#{text}#{space_for(text)}#{description}")
29
+ end
30
+ end
31
+
32
+ def options
33
+ puts ''
34
+ puts 'Opções:'
35
+ puts ''
36
+ end
37
+
38
+ def header
39
+ puts 'Uso: sesc [filtros...] [opções...]'
40
+ end
41
+
42
+ def help
43
+ puts "-h --help#{space_for('-h --help')}Exibe este texto de ajuda"
44
+ end
45
+
46
+ def filters
47
+ puts ''
48
+ puts 'Filtros:'
49
+ puts ''
50
+
51
+ FILTERS.each do |command, description|
52
+ puts("#{command}#{space_for(command)}#{description}")
53
+ end
54
+ end
55
+
56
+ def alias_for(command)
57
+ Sesc::Cli::Options::COMMANDS_WITH_OPTIONS[command].join(' ')
58
+ end
59
+
60
+ def space_for(text)
61
+ ' ' * (15 - text.length)
62
+ end
63
+
64
+ def puts(text)
65
+ Sesc::Exporter::Printer.new(text.to_s).terminal
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Exporter
5
+ class Painter
6
+ attr_accessor :text, :color, :background
7
+
8
+ def initialize(text, options = {})
9
+ self.text = text
10
+ self.color = options.fetch(:color, :light_white)
11
+ self.background = options.fetch(:background, :black)
12
+ end
13
+
14
+ def default
15
+ text.colorize(color: color, background: background)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Exporter
5
+ class Places
6
+ class << self
7
+ def print
8
+ print_cities(Sesc::Cli::Filter::PLACES)
9
+ end
10
+
11
+ private
12
+
13
+ def print_cities(cities, i = 0)
14
+ example
15
+ cities.each do |city, places|
16
+ Sesc::Exporter::Printer.new(city, up: 1).terminal
17
+ places.each do |(place, _)|
18
+ Sesc::Exporter::Printer.new("#{i += 1}. #{place}").terminal
19
+ end
20
+ end
21
+ end
22
+
23
+ def example
24
+ Sesc::Exporter::Printer.new('Example: sesc -p 1,3,10').terminal
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ class Exporter
5
+ class Printer
6
+ attr_accessor :text, :up, :down
7
+
8
+ def initialize(text, params = {})
9
+ self.text = text
10
+ self.up = params.fetch(:up, 0)
11
+ self.down = params.fetch(:down, 0)
12
+ end
13
+
14
+ def terminal
15
+ puts output unless ENV['DISABLE_OUTPUT']
16
+ end
17
+
18
+ private
19
+
20
+ def output
21
+ up_blank_lines + colorize + down_blank_lines
22
+ end
23
+
24
+ def colorize
25
+ text
26
+ end
27
+
28
+ def up_blank_lines
29
+ "\n" * up
30
+ end
31
+
32
+ def down_blank_lines
33
+ "\n" * down
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sesc
4
+ module Parser
5
+ module Sp
6
+ class Body
7
+ def initialize(response)
8
+ @response = response
9
+ end
10
+
11
+ def events
12
+ body.elements.last.search('article')
13
+ end
14
+
15
+ private
16
+
17
+ def body
18
+ document.search('body').first
19
+ end
20
+
21
+ def document
22
+ Nokogiri::HTML(@response)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end