gares 0.1.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 +7 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +36 -0
- data/.travis.yml +19 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +21 -0
- data/README.md +85 -0
- data/Rakefile +27 -0
- data/gares.gemspec +32 -0
- data/lib/gares/base.rb +49 -0
- data/lib/gares/gare.rb +5 -0
- data/lib/gares/gare_list.rb +15 -0
- data/lib/gares/search.rb +48 -0
- data/lib/gares/string_extensions.rb +22 -0
- data/lib/gares/version.rb +3 -0
- data/lib/gares.rb +16 -0
- data/spec/fixtures/frabt +330 -0
- data/spec/fixtures/frhco +346 -0
- data/spec/fixtures/frlpd +365 -0
- data/spec/fixtures/search +5254 -0
- data/spec/gares/gare_spec.rb +36 -0
- data/spec/gares/search_spec.rb +42 -0
- data/spec/spec_helper.rb +40 -0
- data/tasks/fixtures.rake +17 -0
- data/tasks/rspec.rake +21 -0
- metadata +183 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f69434b674f7dce5269749d0101d1bd97b468c8a
|
4
|
+
data.tar.gz: 85cdf302cca179cb12fc017aceb06557db090c1a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 774313d7b1f6f0d42e9b81e841089af25df06a178034edeb416d38eb4b96cc458e6c98a9177b5430e0722533855968c980ef432847ca7196d57e8a8805f5a8a3
|
7
|
+
data.tar.gz: 2e1bbd9c18f5731b28e17a79fd884f22d0c4bfc5c4c4f185b7f84c5a7b92bb3a92dc6c09251b5e7fbb3d9f6dd26ee3d41c55d328f32c6b26b565b535e74018d0
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.rubocop.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2014-06-01 12:18:38 +0200 using RuboCop version 0.22.0.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offenses are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
# Offense count: 1
|
9
|
+
# Configuration parameters: CountComments.
|
10
|
+
ClassLength:
|
11
|
+
Max: 142
|
12
|
+
|
13
|
+
# Offense count: 1
|
14
|
+
CyclomaticComplexity:
|
15
|
+
Max: 8
|
16
|
+
|
17
|
+
# Offense count: 5
|
18
|
+
Documentation:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
# Offense count: 53
|
22
|
+
LineLength:
|
23
|
+
Max: 704
|
24
|
+
|
25
|
+
# Offense count: 2
|
26
|
+
# Configuration parameters: CountComments.
|
27
|
+
MethodLength:
|
28
|
+
Max: 19
|
29
|
+
|
30
|
+
# Offense count: 2
|
31
|
+
MultilineBlockChain:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
# Offense count: 5
|
35
|
+
RescueModifier:
|
36
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2015 Paul Bonaud
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Gares (en-mouvement)
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
The Gares gem allows you to easy access publicly available data from gares-en-mouvement.com.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
Gares currently features the following:
|
10
|
+
|
11
|
+
* Search for a gare
|
12
|
+
* Retrieve complete gare information
|
13
|
+
|
14
|
+
## Examples
|
15
|
+
|
16
|
+
### Gare:
|
17
|
+
|
18
|
+
g = Gares::Gare.new("frabt")
|
19
|
+
|
20
|
+
g.name
|
21
|
+
#=> "Abancourt"
|
22
|
+
|
23
|
+
g.services.first
|
24
|
+
#=> "Borne Automatique"
|
25
|
+
|
26
|
+
### Searching:
|
27
|
+
|
28
|
+
g = Gares::Search.new("Aix")
|
29
|
+
|
30
|
+
g.gares.size
|
31
|
+
#=> 3
|
32
|
+
|
33
|
+
## Installation
|
34
|
+
|
35
|
+
gem install gares
|
36
|
+
|
37
|
+
Or, if you're using this in a project with Bundler:
|
38
|
+
|
39
|
+
gem gares
|
40
|
+
|
41
|
+
## Running Tests
|
42
|
+
|
43
|
+
As this gem uses content from gare-en-mouvement.com, the test suite uses a set of
|
44
|
+
pre-defined fixute files in `spec/fixtures`. These fixtures are
|
45
|
+
copies of gares-en-mouvement page used in tests.
|
46
|
+
|
47
|
+
Run bundle install to install all dependencies, including fakeweb, which
|
48
|
+
will serve the fixture files instead of doing actual requests to gares-en-mouvement.com.
|
49
|
+
|
50
|
+
$ bundle install
|
51
|
+
|
52
|
+
Next, simple run `rake` to run the entire test suite.
|
53
|
+
|
54
|
+
### Running against actual gare-en-mouvement data
|
55
|
+
|
56
|
+
It's possible to run the test suite directly against gares-en-mouvement.com. This has
|
57
|
+
two disadvantages:
|
58
|
+
|
59
|
+
1. Tests will be slow
|
60
|
+
2. Running tests often will probably get you into trouble, see Disclaimer.
|
61
|
+
|
62
|
+
$ LIVE_TEST=true rake
|
63
|
+
|
64
|
+
If you want to run against actual gares-en-mouvement data, it's better to just update
|
65
|
+
the fixture files once with up-to-date content:
|
66
|
+
|
67
|
+
$ rake fixtures:refresh
|
68
|
+
|
69
|
+
When you run the test suite now, it will use the updated fixture files.
|
70
|
+
|
71
|
+
## Disclaimer
|
72
|
+
|
73
|
+
Neither I, nor any developer who contributed to this project, accept any kind of
|
74
|
+
liability for your use of this library.
|
75
|
+
|
76
|
+
gares-en-mouvement does not permit use of its data by third parties without their consent.
|
77
|
+
|
78
|
+
Using this library for anything other than limited personal use may result
|
79
|
+
in an IP ban to the gares-en-mouvement website.
|
80
|
+
|
81
|
+
_This gem is not endorsed or affiliated with gares-en-mouvement.com, or SNCF, Inc._
|
82
|
+
|
83
|
+
## License
|
84
|
+
|
85
|
+
See [MIT-LICENSE](https://github.com/paulrbr/gares/blob/master/MIT-LICENSE)
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
load File.expand_path(File.dirname(__FILE__) + '/tasks/fixtures.rake')
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
task default: :spec
|
10
|
+
|
11
|
+
require 'gares/version'
|
12
|
+
require 'rdoc/task'
|
13
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
14
|
+
rdoc.main = 'README.rdoc'
|
15
|
+
rdoc.rdoc_dir = 'rdoc'
|
16
|
+
rdoc.title = "Gares #{Gares::VERSION} documentation"
|
17
|
+
rdoc.rdoc_files.include('README*')
|
18
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
rdoc.options << '--webcvs=http://github.com/paulrbr/gares/tree/master/'
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'gokdok'
|
23
|
+
Gokdok::Dokker.new do |gd|
|
24
|
+
gd.repo_url = 'git@github.com:paulrbr/gares.git'
|
25
|
+
gd.doc_home = 'rdoc'
|
26
|
+
gd.remote_path = '.'
|
27
|
+
end
|
data/gares.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
2
|
+
require 'gares/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'gares'
|
6
|
+
s.licenses = ['MIT']
|
7
|
+
s.version = Gares::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ['Paul Bonaud']
|
10
|
+
s.email = ['paul+gh@bonaud.fr']
|
11
|
+
s.homepage = 'http://github.com/paulrbr/gares'
|
12
|
+
s.summary = %q(Easily access the publicly available information on gares-en-mouvement.com.)
|
13
|
+
s.description = %q(Easily use Ruby or the command line to find information on gares-en-mouvement.com.)
|
14
|
+
|
15
|
+
s.rubyforge_project = 'gares'
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
20
|
+
s.require_paths = ['lib']
|
21
|
+
|
22
|
+
s.add_dependency 'nokogiri', '~> 1.6'
|
23
|
+
s.add_dependency 'hashie', '~> 0'
|
24
|
+
s.add_dependency 'unidecoder', '~> 0'
|
25
|
+
|
26
|
+
s.add_development_dependency 'rake', '~> 0'
|
27
|
+
s.add_development_dependency 'rspec', '~> 0'
|
28
|
+
s.add_development_dependency 'gokdok', '~> 0'
|
29
|
+
s.add_development_dependency 'rdoc', '~> 0'
|
30
|
+
s.add_development_dependency 'fakeweb', '~> 0'
|
31
|
+
|
32
|
+
end
|
data/lib/gares/base.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Gares
|
2
|
+
# Represents something on gare-en-mouvement.com
|
3
|
+
class Base
|
4
|
+
attr_accessor :slug, :name
|
5
|
+
|
6
|
+
# Initialize a new Gare object with it's gare-en-mouvemnt id (as a String)
|
7
|
+
#
|
8
|
+
# gare = Gares::Gare.new("frabt")
|
9
|
+
#
|
10
|
+
# Gares::Gare objects are lazy loading, meaning that no HTTP request
|
11
|
+
# will be performed when a new object is created. Only when you use an
|
12
|
+
# accessor that needs the remote data, a HTTP request is made (once).
|
13
|
+
#
|
14
|
+
def initialize(slug, name = nil)
|
15
|
+
@slug = slug
|
16
|
+
@name = name if name
|
17
|
+
end
|
18
|
+
|
19
|
+
def horaires
|
20
|
+
document.at('ul.ouverture_heure').inner_html rescue nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns a string containing the name
|
24
|
+
def name(force_refresh = false)
|
25
|
+
if @name && !force_refresh
|
26
|
+
@name
|
27
|
+
else
|
28
|
+
@name = document.at('h1').inner_html.gsub(/En direct de /, '') rescue nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Returns a new Nokogiri document for parsing.
|
35
|
+
def document
|
36
|
+
@document ||= Nokogiri::HTML(Gares::Gare.find_by_slug(@slug))
|
37
|
+
end
|
38
|
+
|
39
|
+
# Use HTTParty to fetch the raw HTML for this movie.
|
40
|
+
def self.find_by_slug(slug, page = :"votre-gare")
|
41
|
+
open("http://www.gares-en-mouvement.com/fr/#{slug}/#{page}")
|
42
|
+
end
|
43
|
+
|
44
|
+
# Convenience method for search
|
45
|
+
def self.search(query)
|
46
|
+
Gares::Search.new(query).gares
|
47
|
+
end
|
48
|
+
end # Gare
|
49
|
+
end # Gares
|
data/lib/gares/gare.rb
ADDED
data/lib/gares/search.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Gares
|
2
|
+
# Search Gares-en-mouvement for a gare name
|
3
|
+
class Search < GareList
|
4
|
+
attr_reader :query
|
5
|
+
|
6
|
+
GARES_LIST_URL = "https://www.kimonolabs.com/api/7jys32dy?apikey=lsOO4tNm78cH9JxqWg9gAk9l4nYaou9j&kimmodify=1"
|
7
|
+
|
8
|
+
# Initialize a new Gares search with the specified query
|
9
|
+
#
|
10
|
+
# search = Gares::Search.new("Aix")
|
11
|
+
#
|
12
|
+
# Gares::Search is lazy loading, meaning that unless you access the +gares+
|
13
|
+
# attribute, no query is made to gares-en-mouvement.com.
|
14
|
+
#
|
15
|
+
def initialize(query)
|
16
|
+
@query = query
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an array of Gares::Gare objects for easy search result yielded.
|
20
|
+
# If the +query+ was an exact match, a single element array will be returned.
|
21
|
+
def gares
|
22
|
+
@gares ||= (exact_match? ? parse_gare : parse_gares)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def document
|
28
|
+
@document ||= Hashie::Mash.new(JSON.load(Gares::Search.query))
|
29
|
+
end
|
30
|
+
|
31
|
+
def result
|
32
|
+
@result ||= document.results.collection1.map(&:station).select { |gare| gare.name.to_ascii =~ /#{@query}/i }
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.query
|
36
|
+
open(GARES_LIST_URL)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_gare
|
40
|
+
gare = result.first
|
41
|
+
[Gares::Gare.new(gare.slug, gare.name)]
|
42
|
+
end
|
43
|
+
|
44
|
+
def exact_match?
|
45
|
+
result.count == 1
|
46
|
+
end
|
47
|
+
end # Search
|
48
|
+
end # Gares
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module Gares #:nordoc:
|
4
|
+
module StringExtensions
|
5
|
+
# Unescape HTML
|
6
|
+
def unescape_html
|
7
|
+
CGI.unescapeHTML(encode('UTF-8'))
|
8
|
+
end
|
9
|
+
|
10
|
+
# Strip tags
|
11
|
+
def strip_tags
|
12
|
+
gsub(/<\/?[^>]*>/, '')
|
13
|
+
end
|
14
|
+
|
15
|
+
# Strips out whitespace then tests if the string is empty.
|
16
|
+
def blank?
|
17
|
+
strip.empty?
|
18
|
+
end unless method_defined?(:blank?)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
String.send :include, Gares::StringExtensions
|
data/lib/gares.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$LOAD_PATH.include?(File.dirname(__FILE__)) || $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'nokogiri'
|
7
|
+
require 'json'
|
8
|
+
require 'hashie'
|
9
|
+
require 'unidecoder'
|
10
|
+
|
11
|
+
require 'gares/base'
|
12
|
+
require 'gares/gare'
|
13
|
+
require 'gares/gare_list'
|
14
|
+
require 'gares/search'
|
15
|
+
require 'gares/string_extensions'
|
16
|
+
require 'gares/version'
|