url_2_event 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +302 -0
- data/CONTRIBUTING.md +124 -0
- data/Gemfile +2 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +22 -0
- data/README.md +64 -0
- data/Rakefile +2 -0
- data/lib/url_2_event.rb +52 -0
- data/lib/url_2_event/adapters/eventbrite.rb +68 -0
- data/lib/url_2_event/adapters/meetup.rb +72 -0
- data/lib/url_2_event/base.rb +43 -0
- data/lib/url_2_event/event.rb +4 -0
- data/lib/url_2_event/version.rb +3 -0
- data/script/console.rb +8 -0
- data/spec/cassettes/Url2Event/_parse_event_from_uri/.yml +95 -0
- data/spec/cassettes/Url2Event_Eventbrite/get_event/.yml +270 -0
- data/spec/cassettes/Url2Event_Eventbrite/get_event/begin_at/.yml +270 -0
- data/spec/cassettes/Url2Event_Eventbrite/get_event/description/.yml +270 -0
- data/spec/cassettes/Url2Event_Eventbrite/get_event/end_at/.yml +270 -0
- data/spec/cassettes/Url2Event_Eventbrite/get_event/link/.yml +270 -0
- data/spec/cassettes/Url2Event_Eventbrite/get_event/location/.yml +270 -0
- data/spec/cassettes/Url2Event_Eventbrite/get_event/title/.yml +270 -0
- data/spec/cassettes/Url2Event_Meetup/get_event/.yml +209 -0
- data/spec/cassettes/Url2Event_Meetup/get_event/begin_at/.yml +209 -0
- data/spec/cassettes/Url2Event_Meetup/get_event/description/.yml +209 -0
- data/spec/cassettes/Url2Event_Meetup/get_event/end_at/.yml +209 -0
- data/spec/cassettes/Url2Event_Meetup/get_event/location/.yml +209 -0
- data/spec/cassettes/Url2Event_Meetup/get_event/price/.yml +209 -0
- data/spec/cassettes/Url2Event_Meetup/get_event/title/.yml +209 -0
- data/spec/eventbrite_spec.rb +33 -0
- data/spec/meetup_spec.rb +31 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/url_2_event_spec.rb +33 -0
- data/url_2_event.gemspec +35 -0
- metadata +295 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 827439573edb14f1cfbfd37bb83f4ad303b2fcb9
|
4
|
+
data.tar.gz: 7384b26ac0e9177fdaf1c7df5aa0feb580ff2eaf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b1b179fc628d6a4d0b987e336cf3372f16a035093117dcfaea14d26480149bfd6be0ad79bc64abe99cd1f1f089ab42be2a0b16f2053da92bec4fea71a7fa3744
|
7
|
+
data.tar.gz: 5ccc67d813ab1f5d6a54c020cfaa70ec088aafe02a6a787612c8532396ecfabf9a95e78cd08e294885edc3eb2ab3773bb5d7d2ab8a2c9190a023d194547edc6e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
AllCops:
|
2
|
+
NoGoZone:
|
3
|
+
- db
|
4
|
+
- script
|
5
|
+
|
6
|
+
# Use UTF-8 as the source file encoding.
|
7
|
+
Encoding:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
# Limit lines to 80 characters.
|
11
|
+
LineLength:
|
12
|
+
Enabled: true
|
13
|
+
Max: 79
|
14
|
+
|
15
|
+
# Avoid methods longer than 10 lines of code
|
16
|
+
MethodLength:
|
17
|
+
Enabled: true
|
18
|
+
CountComments: false # count full line comments?
|
19
|
+
Max: 65
|
20
|
+
|
21
|
+
# No hard tabs.
|
22
|
+
Tab:
|
23
|
+
Enabled: true
|
24
|
+
|
25
|
+
# Avoid trailing whitespace.
|
26
|
+
TrailingWhitespace:
|
27
|
+
Enabled: true
|
28
|
+
|
29
|
+
# Indent when as deep as case.
|
30
|
+
CaseIndentation:
|
31
|
+
Enabled: true
|
32
|
+
|
33
|
+
# Use empty lines between defs.
|
34
|
+
EmptyLineBetweenDefs:
|
35
|
+
Enabled: true
|
36
|
+
|
37
|
+
# Don't use several empty lines in a row.
|
38
|
+
EmptyLines:
|
39
|
+
Enabled: true
|
40
|
+
|
41
|
+
# Use spaces around operators.
|
42
|
+
SpaceAroundOperators:
|
43
|
+
Enabled: true
|
44
|
+
|
45
|
+
# Use spaces around { and before }.
|
46
|
+
SpaceAroundBraces:
|
47
|
+
Enabled: true
|
48
|
+
|
49
|
+
# No spaces after ( or before ).
|
50
|
+
SpaceInsideParens:
|
51
|
+
Enabled: true
|
52
|
+
|
53
|
+
# No spaces after [ or before ].
|
54
|
+
SpaceInsideBrackets:
|
55
|
+
Enabled: true
|
56
|
+
|
57
|
+
# Use spaces after commas.
|
58
|
+
SpaceAfterComma:
|
59
|
+
Enabled: true
|
60
|
+
|
61
|
+
# Use spaces after semicolons.
|
62
|
+
SpaceAfterSemicolon:
|
63
|
+
Enabled: true
|
64
|
+
|
65
|
+
# Use spaces after colons.
|
66
|
+
SpaceAfterColon:
|
67
|
+
Enabled: true
|
68
|
+
|
69
|
+
# Prefer symbols instead of strings as hash keys.
|
70
|
+
HashSyntax:
|
71
|
+
Enabled: true
|
72
|
+
|
73
|
+
# Use Unix-style line endings.
|
74
|
+
EndOfLine:
|
75
|
+
Enabled: true
|
76
|
+
|
77
|
+
# Add underscores to large numeric literals to improve their readability.
|
78
|
+
NumericLiterals:
|
79
|
+
Enabled: true
|
80
|
+
|
81
|
+
# Align the parameters of a method call if they span more than one line.
|
82
|
+
AlignParameters:
|
83
|
+
Enabled: true
|
84
|
+
|
85
|
+
# Use def with parentheses when there are arguments.
|
86
|
+
DefWithParentheses:
|
87
|
+
Enabled: true
|
88
|
+
|
89
|
+
# Omit the parentheses when the method doesn't accept any arguments.
|
90
|
+
DefWithoutParentheses:
|
91
|
+
Enabled: true
|
92
|
+
|
93
|
+
# Never use if x; .... Use the ternary operator instead.
|
94
|
+
IfWithSemicolon:
|
95
|
+
Enabled: true
|
96
|
+
|
97
|
+
# Never use then for multi-line if/unless.
|
98
|
+
MultilineIfThen:
|
99
|
+
Enabled: true
|
100
|
+
|
101
|
+
# Favor the ternary operator(?:) over if/then/else/end constructs.
|
102
|
+
OneLineConditional:
|
103
|
+
Enabled: true
|
104
|
+
|
105
|
+
# Avoid using {...} for multi-line blocks (multiline chaining is always ugly).
|
106
|
+
MultilineBlocks:
|
107
|
+
Enabled: true
|
108
|
+
|
109
|
+
# Prefer {...} over do...end for single-line blocks.
|
110
|
+
SingleLineBlocks:
|
111
|
+
Enabled: true
|
112
|
+
|
113
|
+
# Avoid parameter lists longer than three or four parameters.
|
114
|
+
ParameterLists:
|
115
|
+
Enabled: true
|
116
|
+
|
117
|
+
# Prefer ' strings when you don't need string interpolation or special symbols.
|
118
|
+
StringLiterals:
|
119
|
+
Enabled: false
|
120
|
+
|
121
|
+
# Avoid multi-line ?: (the ternary operator); use if/unless instead.
|
122
|
+
MultilineTernaryOperator:
|
123
|
+
Enabled: true
|
124
|
+
|
125
|
+
# Use one expression per branch in a ternary operator.
|
126
|
+
NestedTernaryOperator:
|
127
|
+
Enabled: true
|
128
|
+
|
129
|
+
# Never use unless with else. Rewrite these with the positive case first.
|
130
|
+
UnlessElse:
|
131
|
+
Enabled: true
|
132
|
+
|
133
|
+
# Use &&/|| for boolean expressions, and/or for control flow.
|
134
|
+
AmpersandsPipesVsAndOr:
|
135
|
+
Enabled: true
|
136
|
+
|
137
|
+
# Use when x then ... for one-line cases.
|
138
|
+
WhenThen:
|
139
|
+
Enabled: true
|
140
|
+
|
141
|
+
# Favor modifier if/unless usage when you have a single-line body.
|
142
|
+
IfUnlessModifier:
|
143
|
+
Enabled: true
|
144
|
+
|
145
|
+
# Favor modifier while/until usage when you have a single-line body.
|
146
|
+
WhileUntilModifier:
|
147
|
+
Enabled: true
|
148
|
+
|
149
|
+
# Favor unless over if for negative conditions (or control flow or).
|
150
|
+
FavorUnlessOverNegatedIf:
|
151
|
+
Enabled: true
|
152
|
+
|
153
|
+
# Favor until over while for negative conditions.
|
154
|
+
FavorUntilOverNegatedWhile:
|
155
|
+
Enabled: true
|
156
|
+
|
157
|
+
# Use spaces around the = operator when assigning default values in def params.
|
158
|
+
SpaceAroundEqualsInParameterDefault:
|
159
|
+
Enabled: true
|
160
|
+
|
161
|
+
# Use the new lambda literal syntax.
|
162
|
+
NewLambdaLiteral:
|
163
|
+
Enabled: true
|
164
|
+
|
165
|
+
# Don't use parentheses around the condition of an if/unless/while.
|
166
|
+
ParenthesesAroundCondition:
|
167
|
+
Enabled: true
|
168
|
+
|
169
|
+
# Use snake_case for symbols, methods and variables.
|
170
|
+
MethodAndVariableSnakeCase:
|
171
|
+
Enabled: true
|
172
|
+
|
173
|
+
# Use CamelCase for classes and modules.
|
174
|
+
ClassAndModuleCamelCase:
|
175
|
+
Enabled: true
|
176
|
+
|
177
|
+
# Causes Ruby to check the syntax of the script and exit without executing.
|
178
|
+
Syntax:
|
179
|
+
Enabled: true
|
180
|
+
|
181
|
+
# Preferred collection methods.
|
182
|
+
CollectionMethods:
|
183
|
+
Enabled: true
|
184
|
+
|
185
|
+
# Prefer each over for.
|
186
|
+
AvoidFor:
|
187
|
+
Enabled: true
|
188
|
+
|
189
|
+
# Avoid Perl-style global variables.
|
190
|
+
AvoidPerlisms:
|
191
|
+
Enabled: true
|
192
|
+
|
193
|
+
# Avoid Perl-style regex back references.
|
194
|
+
AvoidPerlBackrefs:
|
195
|
+
Enabled: true
|
196
|
+
|
197
|
+
# Avoid the use of class variables.
|
198
|
+
AvoidClassVars:
|
199
|
+
Enabled: true
|
200
|
+
|
201
|
+
# Symbol literals should use snake_case.
|
202
|
+
SymbolSnakeCase:
|
203
|
+
Enabled: true
|
204
|
+
|
205
|
+
# Don't interpolate global, instance and class variables directly in strings.
|
206
|
+
VariableInterpolation:
|
207
|
+
Enabled: true
|
208
|
+
|
209
|
+
# Don't use semicolons to terminate expressions.
|
210
|
+
Semicolon:
|
211
|
+
Enabled: true
|
212
|
+
# For example; def area(height, width); height * width end
|
213
|
+
AllowAfterParameterListInOneLineMethods: false
|
214
|
+
# For example; def area(height, width) height * width; end
|
215
|
+
AllowBeforeEndInOneLineMethods: true
|
216
|
+
|
217
|
+
# Use sprintf instead of String#%.
|
218
|
+
FavorSprintf:
|
219
|
+
Enabled: true
|
220
|
+
|
221
|
+
# Use Array#join instead of Array#*.
|
222
|
+
FavorJoin:
|
223
|
+
Enabled: true
|
224
|
+
|
225
|
+
# Use alias_method instead of alias.
|
226
|
+
Alias:
|
227
|
+
Enabled: true
|
228
|
+
|
229
|
+
# Avoid using rescue in its modifier form.
|
230
|
+
RescueModifier:
|
231
|
+
Enabled: true
|
232
|
+
|
233
|
+
# Avoid the use of %q, %Q, %s and %x.
|
234
|
+
PercentLiterals:
|
235
|
+
Enabled: false
|
236
|
+
|
237
|
+
RegexpLiteral:
|
238
|
+
Enabled: false
|
239
|
+
|
240
|
+
UnneededPercentQ:
|
241
|
+
Enabled: false
|
242
|
+
|
243
|
+
# Prefer () as delimiters for all % literals.
|
244
|
+
BraceAfterPercent:
|
245
|
+
Enabled: true
|
246
|
+
|
247
|
+
# Never use return in an ensure block.
|
248
|
+
EnsureReturn:
|
249
|
+
Enabled: true
|
250
|
+
|
251
|
+
# Don't suppress exception.
|
252
|
+
HandleExceptions:
|
253
|
+
Enabled: true
|
254
|
+
|
255
|
+
# Use only ascii symbols in identifiers.
|
256
|
+
AsciiIdentifiers:
|
257
|
+
Enabled: true
|
258
|
+
|
259
|
+
# Use only ascii symbols in comments.
|
260
|
+
AsciiComments:
|
261
|
+
Enabled: true
|
262
|
+
|
263
|
+
# Do not use block comments.
|
264
|
+
BlockComments:
|
265
|
+
Enabled: true
|
266
|
+
|
267
|
+
# Avoid rescuing the Exception class.
|
268
|
+
RescueException:
|
269
|
+
Enabled: true
|
270
|
+
|
271
|
+
# Prefer array literal to Array.new.
|
272
|
+
ArrayLiteral:
|
273
|
+
Enabled: true
|
274
|
+
|
275
|
+
# Prefer hash {} literail to Hash.new.
|
276
|
+
HashLiteral:
|
277
|
+
Enabled: true
|
278
|
+
|
279
|
+
# When defining binary operators, name the argument other.
|
280
|
+
OpMethod:
|
281
|
+
Enabled: true
|
282
|
+
|
283
|
+
# Name reduce arguments |a, e| (accumulator, element)
|
284
|
+
ReduceArguments:
|
285
|
+
Enabled: true
|
286
|
+
|
287
|
+
# Use %r only for regular expressions matching more than one '/' character.
|
288
|
+
PercentR:
|
289
|
+
Enabled: true
|
290
|
+
|
291
|
+
# Use %r for regular expressions matching more than one '/' character.
|
292
|
+
FavorPercentR:
|
293
|
+
Enabled: true
|
294
|
+
|
295
|
+
# Use self when defining module/class methods.
|
296
|
+
ClassMethods:
|
297
|
+
Enabled: true
|
298
|
+
|
299
|
+
# Avoid single-line methods.
|
300
|
+
SingleLineMethods:
|
301
|
+
Enabled: true
|
302
|
+
AllowIfMethodIsEmpty: true
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# Contributing Guidelines
|
2
|
+
|
3
|
+
If you're thinking about contributing to this project, it's likely that you'll want to add support for parsing events from a currently unsupported website. The list of current adapters can be found in [`lib/url_2_events/adapters`](https://github.com/StartupWeekend/url_2_event/tree/master/lib/url_2_event/adapters).
|
4
|
+
|
5
|
+
## Adding a new website adapter
|
6
|
+
|
7
|
+
### Adapter class
|
8
|
+
|
9
|
+
First, get to know how each adapter works. To get started, create a file in the adapters folder called `website_name.rb`, replacing `website_name` with the name of the website you're creating. Create a class under the module `Url2Event` and have the class inherit from `Base`.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
module Url2Event
|
13
|
+
class WebsiteName
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
The major methods you'll need to implement are `to_event(response)`, `options`, `event_endpoint` and `self.is_parser_for?`. You'll also need to call `base_uri 'hostname'` in the class definition. Let's do this for an example website:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
module Url2Event
|
23
|
+
class WebsiteName
|
24
|
+
base_uri 'www.websitename.com'
|
25
|
+
|
26
|
+
# this method should return a boolean, indicating whether
|
27
|
+
# the `uri` given is supported by this adapter.
|
28
|
+
def self.is_parser_for?(uri)
|
29
|
+
!uri.hostname.match(%r{(?:www\.)?websitename\.com}).nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
# return a hash, which will get passed to your http query.
|
33
|
+
# this hash will get passed to `HTTParty`'s `get` method.
|
34
|
+
def options
|
35
|
+
@options = {
|
36
|
+
query: {
|
37
|
+
my_name: "is_good"
|
38
|
+
}
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# return a string indicating the path that to be appended
|
43
|
+
# to `base_uri` for this event. `@uri` is the URL that is passed
|
44
|
+
# to your adapter.
|
45
|
+
def event_endpoint
|
46
|
+
"/api/#{@uri.path.split('/').last}"
|
47
|
+
end
|
48
|
+
|
49
|
+
# return an `Event` model based on the HTTP response you get
|
50
|
+
# after hitting `event_endpoint`. Provide as many details as
|
51
|
+
# possible for this event.
|
52
|
+
def to_event(response)
|
53
|
+
Event.new({
|
54
|
+
title: response['title'],
|
55
|
+
begin_at: response['start_time'],
|
56
|
+
end_at: response['end_time'],
|
57
|
+
location: response['address'],
|
58
|
+
price: response['price'],
|
59
|
+
description: response['description']
|
60
|
+
})
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
Great! You're done setting up your adapter's class, and you're ready to move on to testing. We require that all adapters are tested, otherwise you're contribution won't be accepted.
|
67
|
+
|
68
|
+
### Adapter tests
|
69
|
+
|
70
|
+
To get started, create a new file called `spec/website_name_spec.rb`. Follow [proper rspec patterns](http://betterspecs.org/) while writing tests, and refer to other tests for examples. The goal is to write tests that go through example scenarios and prove that your adapter works the way it should.
|
71
|
+
|
72
|
+
To run tests, run `bundle exec guard` in the command line. As you write code, your tests will be run automatically.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
require 'spec_helper'
|
76
|
+
|
77
|
+
describe Url2Event::WebsiteName do
|
78
|
+
let(:url) { URI.parse("http://www.websitename.com/events/187282242") }
|
79
|
+
describe ".is_parser_for?" do
|
80
|
+
it { expect(described_class.is_parser_for?(url)).to eql(true) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# use `vcr` in any specs that use HTTP requests, otherwise your tests
|
84
|
+
# will fail.
|
85
|
+
describe "get_event", :vcr do
|
86
|
+
let(:begin_at) { Time.parse("2014-07-29 18:00:00 +0000") }
|
87
|
+
let(:end_at) { Time.parse("2014-07-29 21:00:00 +0000") }
|
88
|
+
let(:title) { "Startup Grind Seattle Hosts Robert Scoble, Tech Geek (Rackspace)" }
|
89
|
+
let(:parser) { described_class.new(url) }
|
90
|
+
|
91
|
+
subject { parser.get_event }
|
92
|
+
|
93
|
+
it { should be_instance_of(Event) }
|
94
|
+
its(:title) { should eql(title) }
|
95
|
+
its(:begin_at) { should eql(begin_at) }
|
96
|
+
its(:end_at) { should eql(end_at) }
|
97
|
+
its(:location) { should eql("Dice Cabana at SURF, 821 2nd Avenue #410, Seattle") }
|
98
|
+
its(:price) { should be_nil }
|
99
|
+
|
100
|
+
context "when the url is unparsable" do
|
101
|
+
let(:unparsable) { URI.parse("http://www.websitename.com/Startup-Grind-Seattle") }
|
102
|
+
let(:parser) { described_class.new(unparsable) }
|
103
|
+
subject { parser.get_event }
|
104
|
+
it { should raise_error(Url2Event::UnparsableSourceError) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
This is just an example, and you think for yourself about how your tests should work, and what scenarios you should test. At the least, you should test that:
|
111
|
+
|
112
|
+
- your adapter passes `self.is_adapter_for?` correctly
|
113
|
+
- `get_event` works for valid URLs
|
114
|
+
- `get_event` doesn't work for URLs that aren't parseable, like an 'about' page.
|
115
|
+
|
116
|
+
Make sure all tests pass when you run `rspec`. It's also a good idea to look in `coverage/index.html` to make sure your entire adapter's code is tested. If everything looks good, follow our Git instructions to open a pull request!
|
117
|
+
|
118
|
+
## Git Instructions
|
119
|
+
|
120
|
+
1. Fork it ( https://github.com/startupweekend/url_2_event/fork )
|
121
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
122
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
123
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
124
|
+
5. Create a new Pull Request
|