url_2_event 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +302 -0
  5. data/CONTRIBUTING.md +124 -0
  6. data/Gemfile +2 -0
  7. data/Guardfile +16 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +64 -0
  10. data/Rakefile +2 -0
  11. data/lib/url_2_event.rb +52 -0
  12. data/lib/url_2_event/adapters/eventbrite.rb +68 -0
  13. data/lib/url_2_event/adapters/meetup.rb +72 -0
  14. data/lib/url_2_event/base.rb +43 -0
  15. data/lib/url_2_event/event.rb +4 -0
  16. data/lib/url_2_event/version.rb +3 -0
  17. data/script/console.rb +8 -0
  18. data/spec/cassettes/Url2Event/_parse_event_from_uri/.yml +95 -0
  19. data/spec/cassettes/Url2Event_Eventbrite/get_event/.yml +270 -0
  20. data/spec/cassettes/Url2Event_Eventbrite/get_event/begin_at/.yml +270 -0
  21. data/spec/cassettes/Url2Event_Eventbrite/get_event/description/.yml +270 -0
  22. data/spec/cassettes/Url2Event_Eventbrite/get_event/end_at/.yml +270 -0
  23. data/spec/cassettes/Url2Event_Eventbrite/get_event/link/.yml +270 -0
  24. data/spec/cassettes/Url2Event_Eventbrite/get_event/location/.yml +270 -0
  25. data/spec/cassettes/Url2Event_Eventbrite/get_event/title/.yml +270 -0
  26. data/spec/cassettes/Url2Event_Meetup/get_event/.yml +209 -0
  27. data/spec/cassettes/Url2Event_Meetup/get_event/begin_at/.yml +209 -0
  28. data/spec/cassettes/Url2Event_Meetup/get_event/description/.yml +209 -0
  29. data/spec/cassettes/Url2Event_Meetup/get_event/end_at/.yml +209 -0
  30. data/spec/cassettes/Url2Event_Meetup/get_event/location/.yml +209 -0
  31. data/spec/cassettes/Url2Event_Meetup/get_event/price/.yml +209 -0
  32. data/spec/cassettes/Url2Event_Meetup/get_event/title/.yml +209 -0
  33. data/spec/eventbrite_spec.rb +33 -0
  34. data/spec/meetup_spec.rb +31 -0
  35. data/spec/spec_helper.rb +32 -0
  36. data/spec/url_2_event_spec.rb +33 -0
  37. data/url_2_event.gemspec +35 -0
  38. 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
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .env
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
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