meetupinator 0.6.2 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +23 -9
- data/files/templates/default.html.erb +70 -0
- data/lib/meetupinator/app.rb +17 -5
- data/lib/meetupinator/cli.rb +25 -10
- data/lib/meetupinator/event_finder.rb +2 -2
- data/lib/meetupinator/event_list_file_reader.rb +28 -0
- data/lib/meetupinator/event_list_file_writer.rb +2 -0
- data/lib/meetupinator/formatter.rb +15 -0
- data/lib/meetupinator/template_context.rb +36 -0
- data/lib/meetupinator/version.rb +1 -1
- data/lib/meetupinator.rb +4 -1
- data/spec/fixtures/formatInput.csv +1 -0
- data/spec/fixtures/formatOutput.html +90 -0
- data/spec/fixtures/{functional.csv → retrieveOutput.csv} +0 -0
- data/spec/functional/cli_spec.rb +30 -1
- data/spec/lib/meetupinator/app_spec.rb +34 -8
- data/spec/lib/meetupinator/event_list_file_reader_spec.rb +49 -0
- data/spec/lib/meetupinator/formatter_spec.rb +32 -0
- data/spec/lib/meetupinator/template_context_spec.rb +48 -0
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e41038a73b4ca7867929fba449b8136bf2c37541
|
4
|
+
data.tar.gz: 6babc2eb652d6b1777506fb778519066773a5b26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ed9720f9f2ca68aabc6d413e50fc4068af0a7ac4c9fc1ddbdded0ae37f2c13659e4651f78986ee0c42aa72bb616eea70541ce4fa24b82cf38ac33ee7aa73648
|
7
|
+
data.tar.gz: b44579126afe89cec6001c508c2fe078bde94540dd3d4a2a0b57089c50267becb2aa89d84824a64ea51e2e502b5ebadce87fbfb4271ec9281efcb83e04ffaebd
|
data/README.md
CHANGED
@@ -7,28 +7,42 @@ Give it a list of meetup names you're interested in and then run it and it can t
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/meetupinator.svg)](http://badge.fury.io/rb/meetupinator)
|
8
8
|
|
9
9
|
# What does it do atm?
|
10
|
-
Reads in a list of meetups from a file and writes a csv of all the ones that have future events.
|
10
|
+
* Reads in a list of meetups from a file and writes a csv of all the ones that have future events.
|
11
|
+
* Reads in a list of meetups from a CSV file and uses an ERB template to format that list nicely.
|
11
12
|
|
12
13
|
# Usage
|
14
|
+
## Retrieving events
|
15
|
+
You must specify a input file and key or have your key in your ENV as MEETUP_API_KEY
|
13
16
|
```
|
14
|
-
$ meetupinator
|
17
|
+
$ meetupinator -i /location/of/input.txt -o /location/of/output.csv -k your_api_key_1234abcd -w 1
|
15
18
|
```
|
16
|
-
or
|
19
|
+
or this will get all the up and coming events
|
17
20
|
```
|
18
|
-
$ meetupinator
|
21
|
+
$ meetupinator -i /location/of/input.txt
|
19
22
|
```
|
23
|
+
or for two weeks worth of events
|
24
|
+
```
|
25
|
+
$ meetupinator -i /location/of/input.txt -w 2
|
26
|
+
```
|
27
|
+
|
20
28
|
This will write a otuput.csv to the current directory.
|
21
29
|
|
30
|
+
## Formatting
|
31
|
+
```
|
32
|
+
$ meetupinator format -i /location/of/input.csv -o /location/of/output.whatever -t /location/of/template.whatever.erb
|
33
|
+
```
|
34
|
+
|
35
|
+
or, to use the default output location (output.html) and default template:
|
36
|
+
|
37
|
+
```
|
38
|
+
$ meetupinator format -i /location/of/input.csv -o /location/of/output.whatever -t /location/of/template.whatever.erb
|
39
|
+
```
|
40
|
+
|
22
41
|
## During development
|
23
42
|
|
24
43
|
```
|
25
44
|
$ bundle exec ./bin/meetupinator ...
|
26
45
|
```
|
27
46
|
|
28
|
-
# todo
|
29
|
-
- [x] - given a file input and an output dir write a file
|
30
|
-
- [ ] - provide options for date range
|
31
|
-
- [x] - Gem this
|
32
|
-
|
33
47
|
# Licence
|
34
48
|
[MIT](https://github.com/joesustaric/meetupinator/blob/master/LICENSE.md)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<style>
|
4
|
+
body {
|
5
|
+
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
6
|
+
font-size: 14px;
|
7
|
+
}
|
8
|
+
|
9
|
+
h1 {
|
10
|
+
font-size: 16px;
|
11
|
+
margin-top: 25px;
|
12
|
+
margin-bottom: 5px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.time {
|
16
|
+
float: left;
|
17
|
+
}
|
18
|
+
|
19
|
+
.time-group {
|
20
|
+
margin-left: 80px;
|
21
|
+
}
|
22
|
+
|
23
|
+
.event-name {
|
24
|
+
margin-bottom: 0;
|
25
|
+
}
|
26
|
+
|
27
|
+
.meetup {
|
28
|
+
color: #707070;
|
29
|
+
margin-bottom: 10px;
|
30
|
+
}
|
31
|
+
|
32
|
+
a {
|
33
|
+
text-decoration: none;
|
34
|
+
}
|
35
|
+
|
36
|
+
a:hover {
|
37
|
+
text-decoration: underline;
|
38
|
+
}
|
39
|
+
</style>
|
40
|
+
</head>
|
41
|
+
<body>
|
42
|
+
<%
|
43
|
+
first_meetup = sorted_events.first
|
44
|
+
first_day = first_meetup[:date]
|
45
|
+
start_of_week = get_start_of_week(first_day)
|
46
|
+
days = days_list(start_of_week, 5)
|
47
|
+
%>
|
48
|
+
<% for day in days %>
|
49
|
+
<h1><%= day.strftime('%A %-d/%m/%Y') %></h1>
|
50
|
+
|
51
|
+
<% day_events = sorted_events.select { |event| event[:date] == day } %>
|
52
|
+
|
53
|
+
<% if day_events.empty? %>
|
54
|
+
<div>(none)</div>
|
55
|
+
<% else %>
|
56
|
+
<% day_events.group_by { |event| event[:start_time] }.each do |time, time_events| %>
|
57
|
+
<div class="time"><%= time.strftime('%-l:%M %P') %></div>
|
58
|
+
<div class="time-group">
|
59
|
+
<% for event in time_events %>
|
60
|
+
<div class="meetup">
|
61
|
+
<div class="event-name"><a href="<%= event[:event_url] %>"><%= event[:event_name] %></a></div>
|
62
|
+
<div><%= event[:group_name] %></div>
|
63
|
+
</div>
|
64
|
+
<% end %>
|
65
|
+
</div>
|
66
|
+
<% end %>
|
67
|
+
<% end %>
|
68
|
+
<% end %>
|
69
|
+
</body>
|
70
|
+
</html>
|
data/lib/meetupinator/app.rb
CHANGED
@@ -5,21 +5,33 @@ module Meetupinator
|
|
5
5
|
'meetupinator v' + Meetupinator::VERSION
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.
|
9
|
-
new.
|
8
|
+
def self.retrieve_events(args = {})
|
9
|
+
new.retrieve_events(args)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def self.format(args = {})
|
13
|
+
new.format(args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def retrieve_events(args)
|
17
|
+
init_retrieve(args)
|
14
18
|
events = @event_finder.extract_events(@group_names, @api, args[:weeks])
|
15
19
|
@event_list_file_writer.write events, args[:output]
|
16
20
|
end
|
17
21
|
|
18
|
-
def
|
22
|
+
def init_retrieve(args)
|
19
23
|
@api = Meetupinator::MeetupAPI.new(args[:meetup_api_key])
|
20
24
|
@group_names = Meetupinator::InputFileReader.group_names args[:input]
|
21
25
|
@event_finder = Meetupinator::EventFinder.new
|
22
26
|
@event_list_file_writer = Meetupinator::EventListFileWriter.new
|
23
27
|
end
|
28
|
+
|
29
|
+
def format(args)
|
30
|
+
reader = Meetupinator::EventListFileReader.new
|
31
|
+
formatter = Meetupinator::Formatter.new
|
32
|
+
|
33
|
+
events = reader.read(args[:input])
|
34
|
+
formatter.format(events, args[:template], args[:output])
|
35
|
+
end
|
24
36
|
end
|
25
37
|
end
|
data/lib/meetupinator/cli.rb
CHANGED
@@ -11,24 +11,39 @@ module Meetupinator
|
|
11
11
|
|
12
12
|
class_option :meetup_api_key,
|
13
13
|
type: :string, aliases: '-k',
|
14
|
-
desc: 'API key for the meetup.com API,
|
15
|
-
defaults to MEETUP_API_KEY environment
|
16
|
-
variable if not set'
|
14
|
+
desc: 'API key for the meetup.com API, defaults to MEETUP_API_KEY environment variable if not set'
|
17
15
|
|
18
16
|
desc 'getevents', 'Write all upcoming events for the given meetup
|
19
17
|
groups specified in INPUT to OUTPUT'
|
20
|
-
map 'getevents' => '
|
18
|
+
map 'getevents' => 'retrieve_events'
|
21
19
|
method_option :input, aliases: '-i', required: true, type: :string,
|
22
|
-
desc: 'The location of the input file'
|
20
|
+
desc: 'The location of the input file.'
|
23
21
|
method_option :output,
|
24
22
|
aliases: '-o', required: false, type: :string,
|
25
23
|
default: 'output.csv',
|
26
24
|
desc: 'The name of the file you want to output. (default is ./output.csv)'
|
25
|
+
method_option :weeks,
|
26
|
+
aliases: '-w', required: false, type: :numeric,
|
27
|
+
desc: 'Number of weeks to retrieve events for.'
|
28
|
+
def retrieve_events
|
29
|
+
Meetupinator::App.retrieve_events(options)
|
30
|
+
puts "Output written to #{options[:output]}"
|
31
|
+
end
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
33
|
+
desc 'format', 'Write a formatted version of the events listed in INPUT to a file using a template to specify the desired output format.'
|
34
|
+
method_option :input,
|
35
|
+
aliases: '-i', required: true, type: :string,
|
36
|
+
desc: 'The location of the input CSV file.'
|
37
|
+
method_option :output,
|
38
|
+
aliases: '-o', required: false, type: :string,
|
39
|
+
default: 'output.html',
|
40
|
+
desc: 'The name of the file you want to output.'
|
41
|
+
method_option :template,
|
42
|
+
aliases: '-t', required: false, type: :string,
|
43
|
+
default: File.expand_path("#{File.dirname(__FILE__)}/../../files/templates/default.html.erb"),
|
44
|
+
desc: 'The name of the template file.'
|
45
|
+
def format
|
46
|
+
Meetupinator::App.format(options)
|
32
47
|
puts "Output written to #{options[:output]}"
|
33
48
|
end
|
34
49
|
|
@@ -39,7 +54,7 @@ module Meetupinator
|
|
39
54
|
puts Meetupinator::App.version
|
40
55
|
end
|
41
56
|
|
42
|
-
default_task :
|
57
|
+
default_task :retrieve_events
|
43
58
|
end
|
44
59
|
end
|
45
60
|
# rubocop:enable Metrics/LineLength
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Meetupinator
|
2
2
|
# class def
|
3
3
|
class EventFinder
|
4
|
-
def extract_events(group_url_names, api,
|
4
|
+
def extract_events(group_url_names, api, weeks)
|
5
5
|
ids = group_url_names.map { |name| api.get_meetup_id name }
|
6
6
|
|
7
|
-
api.get_upcoming_events(ids,
|
7
|
+
api.get_upcoming_events(ids, weeks)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Meetupinator
|
2
|
+
# Reads a list of events from a CSV file.
|
3
|
+
class EventListFileReader
|
4
|
+
def read(file_name)
|
5
|
+
File.open file_name do |body|
|
6
|
+
csv = CSV.new(body,
|
7
|
+
headers: true,
|
8
|
+
header_converters: :symbol,
|
9
|
+
converters: :all)
|
10
|
+
csv.to_a.map(&:to_hash).each { |event| parse_dates(event) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def parse_dates(event)
|
17
|
+
event[:start_time] = parse_time_on_date(event[:date], event[:start_time])
|
18
|
+
event[:end_time] = parse_time_on_date(event[:date], event[:end_time])
|
19
|
+
event[:date] = Time.strptime(event[:date], '%d/%m/%Y')
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_time_on_date(date, time)
|
23
|
+
time_format = '%d/%m/%Y %I:%M %p'
|
24
|
+
time_with_date = date + ' ' + time
|
25
|
+
Time.strptime(time_with_date, time_format)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -4,6 +4,8 @@ module Meetupinator
|
|
4
4
|
# class def
|
5
5
|
class EventListFileWriter
|
6
6
|
def write(events, file_name)
|
7
|
+
FileUtils.mkdir_p(File.dirname(file_name))
|
8
|
+
|
7
9
|
CSV.open(file_name, 'wb') do |csv|
|
8
10
|
csv << ['Group name', 'Event name', 'Day of week', 'Date',
|
9
11
|
'Start time', 'End time', 'Event URL']
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Meetupinator
|
4
|
+
# Creates a nicely-formatted version of a list of events.
|
5
|
+
class Formatter
|
6
|
+
def format(events, template_file, output_file)
|
7
|
+
template_engine = ERB.new(File.read(template_file))
|
8
|
+
parameters = TemplateContext.new(events)
|
9
|
+
output = template_engine.result(parameters.template_binding)
|
10
|
+
|
11
|
+
FileUtils.mkdir_p(File.dirname(output_file))
|
12
|
+
File.write(output_file, output)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Meetupinator
|
2
|
+
# Object passed to templates during formatting.
|
3
|
+
class TemplateContext
|
4
|
+
attr_reader :events
|
5
|
+
|
6
|
+
DAY = 60 * 60 * 24
|
7
|
+
|
8
|
+
def initialize(events)
|
9
|
+
@events = events
|
10
|
+
end
|
11
|
+
|
12
|
+
# FIXME: This will probably break for daylight savings
|
13
|
+
def get_start_of_week(d)
|
14
|
+
d -= DAY until d.monday?
|
15
|
+
d
|
16
|
+
end
|
17
|
+
|
18
|
+
def sorted_events
|
19
|
+
events.sort { |a, b| a[:start_time] <=> b[:start_time] }
|
20
|
+
end
|
21
|
+
|
22
|
+
def days_list(start_date, n)
|
23
|
+
(0..(n - 1)).map { |d| add_days(start_date, d) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def template_binding
|
27
|
+
binding
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def add_days(date, n)
|
33
|
+
date + n * DAY
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/meetupinator/version.rb
CHANGED
data/lib/meetupinator.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'meetupinator/app'
|
2
2
|
require 'meetupinator/cli'
|
3
3
|
require 'meetupinator/event_finder'
|
4
|
+
require 'meetupinator/event_list_file_reader'
|
4
5
|
require 'meetupinator/event_list_file_writer'
|
6
|
+
require 'meetupinator/formatter'
|
7
|
+
require 'meetupinator/input_file_reader'
|
5
8
|
require 'meetupinator/meetup_api'
|
9
|
+
require 'meetupinator/template_context'
|
6
10
|
require 'meetupinator/version'
|
7
|
-
require 'meetupinator/input_file_reader'
|
@@ -0,0 +1 @@
|
|
1
|
+
Group name,Event name,Day of week,Date,Start time,End time,Event URL
|
@@ -0,0 +1,90 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<style>
|
4
|
+
body {
|
5
|
+
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
6
|
+
font-size: 14px;
|
7
|
+
}
|
8
|
+
|
9
|
+
h1 {
|
10
|
+
font-size: 16px;
|
11
|
+
margin-top: 25px;
|
12
|
+
margin-bottom: 5px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.time {
|
16
|
+
float: left;
|
17
|
+
}
|
18
|
+
|
19
|
+
.time-group {
|
20
|
+
margin-left: 80px;
|
21
|
+
}
|
22
|
+
|
23
|
+
.event-name {
|
24
|
+
margin-bottom: 0;
|
25
|
+
}
|
26
|
+
|
27
|
+
.meetup {
|
28
|
+
color: #707070;
|
29
|
+
margin-bottom: 10px;
|
30
|
+
}
|
31
|
+
|
32
|
+
a {
|
33
|
+
text-decoration: none;
|
34
|
+
}
|
35
|
+
|
36
|
+
a:hover {
|
37
|
+
text-decoration: underline;
|
38
|
+
}
|
39
|
+
</style>
|
40
|
+
</head>
|
41
|
+
<body>
|
42
|
+
<h1>Monday 16/02/2015</h1>
|
43
|
+
<div>(none)</div>
|
44
|
+
|
45
|
+
<h1>Tuesday 17/02/2015</h1>
|
46
|
+
|
47
|
+
<div class="time">3:00 pm</div>
|
48
|
+
<div class="time-group">
|
49
|
+
<div class="meetup">
|
50
|
+
<div class="event-name"><a href="http://www.fun.com/Tuesday">Fun Stuff</a></div>
|
51
|
+
<div>Tuesday Funtimes</div>
|
52
|
+
</div>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
<div class="time">7:00 pm</div>
|
56
|
+
<div class="time-group">
|
57
|
+
<div class="meetup">
|
58
|
+
<div class="event-name"><a href="http://www.fun.com/Tuesday/Later">Later Fun Stuff</a></div>
|
59
|
+
<div>Tuesday Funtimes</div>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
|
63
|
+
<h1>Wednesday 18/02/2015</h1>
|
64
|
+
<div>(none)</div>
|
65
|
+
|
66
|
+
<h1>Thursday 19/02/2015</h1>
|
67
|
+
|
68
|
+
<div class="time">6:30 pm</div>
|
69
|
+
<div class="time-group">
|
70
|
+
<div class="meetup">
|
71
|
+
<div class="event-name"><a href="http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219051382/">Ruby on Rails InstallFest</a></div>
|
72
|
+
<div>Ruby and Rails Melbourne</div>
|
73
|
+
</div>
|
74
|
+
<div class="meetup">
|
75
|
+
<div class="event-name"><a href="http://www.fun.com/Thursday">Fun Stuff</a></div>
|
76
|
+
<div>Thursday Funtimes</div>
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
|
80
|
+
<h1>Friday 20/02/2015</h1>
|
81
|
+
|
82
|
+
<div class="time">7:00 pm</div>
|
83
|
+
<div class="time-group">
|
84
|
+
<div class="meetup">
|
85
|
+
<div class="event-name"><a href="http://www.melbjs.com/jsfest/">JSFest</a></div>
|
86
|
+
<div>MelbJS</div>
|
87
|
+
</div>
|
88
|
+
</div>
|
89
|
+
</body>
|
90
|
+
</html>
|
File without changes
|
data/spec/functional/cli_spec.rb
CHANGED
@@ -24,15 +24,44 @@ describe 'The meetupinator command line interface' do
|
|
24
24
|
context 'no arguments' do
|
25
25
|
end
|
26
26
|
|
27
|
+
def prepare_html_for_comparison(html)
|
28
|
+
# Replace consecutive spaces with a single space, remove leading spaces at the start of a line, remove multiple blank lines
|
29
|
+
html.gsub(/[ ]+/, ' ').gsub(/^[ ]+/, '').gsub(/\n+/, "\n")
|
30
|
+
end
|
31
|
+
|
27
32
|
context 'meetup api and input file specified' do
|
28
33
|
it 'generates the correct output.csv in the working dir' do
|
29
34
|
VCR.use_cassette('functional') do
|
30
35
|
Meetupinator::CLI.start(['-i', 'input.txt', '-k', '1234'])
|
31
36
|
end
|
32
|
-
expect(CSV.read('output.csv')).to eq(CSV.read('../spec/fixtures/
|
37
|
+
expect(CSV.read('output.csv')).to eq(CSV.read('../spec/fixtures/retrieveOutput.csv'))
|
33
38
|
end
|
34
39
|
end
|
35
40
|
|
36
41
|
context 'meetup api and input file and output file specified' do
|
42
|
+
it 'generates the correct output in the specified location' do
|
43
|
+
VCR.use_cassette('functional') do
|
44
|
+
Meetupinator::CLI.start(['-i', 'input.txt', '-o', 'outputDir/mySpecialOutput.csv', '-k', '1234'])
|
45
|
+
end
|
46
|
+
expect(CSV.read('outputDir/mySpecialOutput.csv')).to eq(CSV.read('../spec/fixtures/retrieveOutput.csv'))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'formatting output' do
|
51
|
+
it 'generates the correct output in the specified location' do
|
52
|
+
Meetupinator::CLI.start(['format', '-i', '../spec/fixtures/formatInput.csv',
|
53
|
+
'-o', 'outputDir/formattedOutput.md',
|
54
|
+
'-t', '../files/templates/default.html.erb'])
|
55
|
+
output = prepare_html_for_comparison(IO.read('outputDir/formattedOutput.md'))
|
56
|
+
expected_output = prepare_html_for_comparison(IO.read('../spec/fixtures/formatOutput.html'))
|
57
|
+
expect(output).to eq(expected_output)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'generates the correct output in the default location using the default template' do
|
61
|
+
Meetupinator::CLI.start(['format', '-i', '../spec/fixtures/formatInput.csv'])
|
62
|
+
output = prepare_html_for_comparison(IO.read('output.html'))
|
63
|
+
expected_output = prepare_html_for_comparison(IO.read('../spec/fixtures/formatOutput.html'))
|
64
|
+
expect(output).to eq(expected_output)
|
65
|
+
end
|
37
66
|
end
|
38
67
|
end
|
@@ -3,12 +3,12 @@ require 'spec_helper'
|
|
3
3
|
require 'meetupinator/app'
|
4
4
|
|
5
5
|
describe Meetupinator::App do
|
6
|
-
describe '#
|
6
|
+
describe '#retrieve_events' do
|
7
|
+
let(:event_finder) { instance_double(Meetupinator::EventFinder) }
|
8
|
+
let(:file_writer) { instance_double(Meetupinator::EventListFileWriter) }
|
9
|
+
let(:meetup_api) { instance_double(Meetupinator::MeetupAPI) }
|
7
10
|
let(:input_file) { 'input.txt' }
|
8
11
|
let(:output_file) { 'output.csv' }
|
9
|
-
let(:event_finder) { double('event finder') }
|
10
|
-
let(:file_writer) { double('file writer') }
|
11
|
-
let(:meetup_api) { double('meetup api') }
|
12
12
|
let(:group_names) { ['First meetup group', 'Second meetup group'] }
|
13
13
|
let(:events) { double('events') }
|
14
14
|
let(:args) do
|
@@ -20,15 +20,41 @@ describe Meetupinator::App do
|
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
-
context 'when input file
|
23
|
+
context 'when input file, output file, api key and number of weeks are specified' do
|
24
24
|
it 'executes the program' do
|
25
|
-
expect(Meetupinator::MeetupAPI).to receive(:new).and_return(meetup_api)
|
26
|
-
expect(Meetupinator::InputFileReader).to receive(:group_names).with(input_file).and_return(group_names)
|
27
25
|
expect(Meetupinator::EventFinder).to receive(:new).and_return(event_finder)
|
28
26
|
expect(Meetupinator::EventListFileWriter).to receive(:new).and_return(file_writer)
|
27
|
+
expect(Meetupinator::MeetupAPI).to receive(:new).and_return(meetup_api)
|
28
|
+
expect(Meetupinator::InputFileReader).to receive(:group_names).with(input_file).and_return(group_names)
|
29
29
|
expect(event_finder).to receive(:extract_events).with(group_names, meetup_api, 1).and_return(events)
|
30
30
|
expect(file_writer).to receive(:write).with(events, output_file)
|
31
|
-
Meetupinator::App.
|
31
|
+
Meetupinator::App.retrieve_events(args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#format' do
|
37
|
+
let(:file_reader) { instance_double(Meetupinator::EventListFileReader) }
|
38
|
+
let(:formatter) { instance_double(Meetupinator::Formatter) }
|
39
|
+
let(:input_file) { 'input.csv' }
|
40
|
+
let(:output_file) { 'output.md' }
|
41
|
+
let(:template_file) { 'template.md.erb' }
|
42
|
+
let(:events) { double('events') }
|
43
|
+
let(:args) do
|
44
|
+
{
|
45
|
+
input: input_file,
|
46
|
+
output: output_file,
|
47
|
+
template: template_file
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when input file, output file and template are specified' do
|
52
|
+
it 'formats the given events using the given template and saves the output to the specified output filename' do
|
53
|
+
expect(Meetupinator::EventListFileReader).to receive(:new).and_return(file_reader)
|
54
|
+
expect(Meetupinator::Formatter).to receive(:new).and_return(formatter)
|
55
|
+
expect(file_reader).to receive(:read).with(input_file).and_return(events)
|
56
|
+
expect(formatter).to receive(:format).with(events, template_file, output_file)
|
57
|
+
Meetupinator::App.format(args)
|
32
58
|
end
|
33
59
|
end
|
34
60
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'fakefs/spec_helpers'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'meetupinator/event_list_file_reader'
|
4
|
+
|
5
|
+
describe Meetupinator::EventListFileReader do
|
6
|
+
include FakeFS::SpecHelpers::All
|
7
|
+
|
8
|
+
let(:file_name) { 'input.csv' }
|
9
|
+
let(:input) do
|
10
|
+
[
|
11
|
+
'Group name,Event name,Day of week,Date,Start time,End time,Event URL',
|
12
|
+
'Ruby and Rails Melbourne,Ruby on Rails InstallFest,Thursday,19/02/2015,6:30 pm,9:00 pm,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219051382/',
|
13
|
+
'Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,25/02/2015,6:00 pm,9:00 pm,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219387830/'
|
14
|
+
].join("\n")
|
15
|
+
end
|
16
|
+
let(:expected_output) do
|
17
|
+
[
|
18
|
+
{
|
19
|
+
group_name: 'Ruby and Rails Melbourne',
|
20
|
+
event_name: 'Ruby on Rails InstallFest',
|
21
|
+
day_of_week: 'Thursday',
|
22
|
+
date: Time.new(2015, 2, 19),
|
23
|
+
start_time: Time.new(2015, 2, 19, 18, 30),
|
24
|
+
end_time: Time.new(2015, 2, 19, 21, 0),
|
25
|
+
event_url: 'http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219051382/'
|
26
|
+
},
|
27
|
+
{
|
28
|
+
group_name: 'Ruby and Rails Melbourne',
|
29
|
+
event_name: 'Melbourne Ruby',
|
30
|
+
day_of_week: 'Wednesday',
|
31
|
+
date: Time.new(2015, 2, 25),
|
32
|
+
start_time: Time.new(2015, 2, 25, 18, 0),
|
33
|
+
end_time: Time.new(2015, 2, 25, 21, 0),
|
34
|
+
event_url: 'http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219387830/'
|
35
|
+
}
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
before do
|
40
|
+
File.write(file_name, input)
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#read' do
|
44
|
+
it 'should read all events from the file' do
|
45
|
+
output = subject.read file_name
|
46
|
+
expect(output).to eq(expected_output)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'fakefs/spec_helpers'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'meetupinator/formatter'
|
4
|
+
|
5
|
+
describe Meetupinator::Formatter do
|
6
|
+
include FakeFS::SpecHelpers::All
|
7
|
+
|
8
|
+
let(:template) { 'template content' }
|
9
|
+
let(:template_file) { 'template.erb' }
|
10
|
+
let(:events) { double('events') }
|
11
|
+
let(:output) { 'output' }
|
12
|
+
let(:output_file) { 'output.blah' }
|
13
|
+
let(:erb) { instance_double(ERB) }
|
14
|
+
|
15
|
+
describe '#format' do
|
16
|
+
before do
|
17
|
+
File.write(template_file, template)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'passes the events to the formatter and saves the result to file' do
|
21
|
+
expect(ERB).to receive(:new).with(template).and_return(erb)
|
22
|
+
expect(erb).to receive(:result) do |binding|
|
23
|
+
expect(eval('events', binding)).to eq(events) # rubocop:disable Lint/Eval
|
24
|
+
output
|
25
|
+
end
|
26
|
+
|
27
|
+
subject.format(events, template_file, output_file)
|
28
|
+
|
29
|
+
expect(File.read(output_file)).to eq(output)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'fakefs/spec_helpers'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'meetupinator/formatter'
|
4
|
+
|
5
|
+
describe Meetupinator::TemplateContext do
|
6
|
+
let(:events) do
|
7
|
+
[
|
8
|
+
{
|
9
|
+
event_name: 'Event A',
|
10
|
+
start_time: Time.new(2015, 03, 21, 7, 0)
|
11
|
+
},
|
12
|
+
{
|
13
|
+
event_name: 'Event B',
|
14
|
+
start_time: Time.new(2015, 03, 19, 7, 0)
|
15
|
+
},
|
16
|
+
{
|
17
|
+
event_name: 'Event C',
|
18
|
+
start_time: Time.new(2015, 03, 19, 8, 0)
|
19
|
+
}
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
subject do
|
24
|
+
Meetupinator::TemplateContext.new(events)
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#get_start_of_week' do
|
28
|
+
it 'returns the given day if it is a Monday' do
|
29
|
+
expect(subject.get_start_of_week(Time.new(2015, 3, 16))).to eq(Time.new(2015, 3, 16))
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns the previous Monday if the day is not a Monday' do
|
33
|
+
expect(subject.get_start_of_week(Time.new(2015, 3, 22))).to eq(Time.new(2015, 3, 16))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#sorted_events' do
|
38
|
+
it 'returns the events in order sorted by start time' do
|
39
|
+
expect(subject.sorted_events.map { |e| e[:event_name] }).to eq(['Event B', 'Event C', 'Event A'])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#days_list' do
|
44
|
+
it 'returns a list of days starting with the day given' do
|
45
|
+
expect(subject.days_list(Time.new(2015, 3, 19), 3)).to eq([Time.new(2015, 3, 19), Time.new(2015, 3, 20), Time.new(2015, 3, 21)])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meetupinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.7'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Sustaric
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-03-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -164,22 +164,31 @@ extra_rdoc_files: []
|
|
164
164
|
files:
|
165
165
|
- README.md
|
166
166
|
- bin/meetupinator
|
167
|
+
- files/templates/default.html.erb
|
167
168
|
- lib/meetupinator.rb
|
168
169
|
- lib/meetupinator/app.rb
|
169
170
|
- lib/meetupinator/cli.rb
|
170
171
|
- lib/meetupinator/event_finder.rb
|
172
|
+
- lib/meetupinator/event_list_file_reader.rb
|
171
173
|
- lib/meetupinator/event_list_file_writer.rb
|
174
|
+
- lib/meetupinator/formatter.rb
|
172
175
|
- lib/meetupinator/input_file_reader.rb
|
173
176
|
- lib/meetupinator/meetup_api.rb
|
177
|
+
- lib/meetupinator/template_context.rb
|
174
178
|
- lib/meetupinator/version.rb
|
175
|
-
- spec/fixtures/
|
179
|
+
- spec/fixtures/formatInput.csv
|
180
|
+
- spec/fixtures/formatOutput.html
|
181
|
+
- spec/fixtures/retrieveOutput.csv
|
176
182
|
- spec/functional/cli_spec.rb
|
177
183
|
- spec/lib/meetupinator/app_spec.rb
|
178
184
|
- spec/lib/meetupinator/event_finder_spec.rb
|
185
|
+
- spec/lib/meetupinator/event_list_file_reader_spec.rb
|
179
186
|
- spec/lib/meetupinator/event_list_file_writer_spec.rb
|
187
|
+
- spec/lib/meetupinator/formatter_spec.rb
|
180
188
|
- spec/lib/meetupinator/functional_spec.rb
|
181
189
|
- spec/lib/meetupinator/input_file_reader_spec.rb
|
182
190
|
- spec/lib/meetupinator/meetup_api_spec.rb
|
191
|
+
- spec/lib/meetupinator/template_context_spec.rb
|
183
192
|
- spec/spec_helper.rb
|
184
193
|
- spec/test_helpers/match_stdout.rb
|
185
194
|
- spec/vcr_cassettes/events_multiple_groups.yml
|
@@ -214,14 +223,19 @@ signing_key:
|
|
214
223
|
specification_version: 4
|
215
224
|
summary: Tool to generate weekly meetup emails
|
216
225
|
test_files:
|
217
|
-
- spec/fixtures/
|
226
|
+
- spec/fixtures/formatInput.csv
|
227
|
+
- spec/fixtures/formatOutput.html
|
228
|
+
- spec/fixtures/retrieveOutput.csv
|
218
229
|
- spec/functional/cli_spec.rb
|
219
230
|
- spec/lib/meetupinator/app_spec.rb
|
220
231
|
- spec/lib/meetupinator/event_finder_spec.rb
|
232
|
+
- spec/lib/meetupinator/event_list_file_reader_spec.rb
|
221
233
|
- spec/lib/meetupinator/event_list_file_writer_spec.rb
|
234
|
+
- spec/lib/meetupinator/formatter_spec.rb
|
222
235
|
- spec/lib/meetupinator/functional_spec.rb
|
223
236
|
- spec/lib/meetupinator/input_file_reader_spec.rb
|
224
237
|
- spec/lib/meetupinator/meetup_api_spec.rb
|
238
|
+
- spec/lib/meetupinator/template_context_spec.rb
|
225
239
|
- spec/spec_helper.rb
|
226
240
|
- spec/test_helpers/match_stdout.rb
|
227
241
|
- spec/vcr_cassettes/events_multiple_groups.yml
|