papercall 0.15.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CODE_OF_CONDUCT.md +1 -1
- data/Guardfile +3 -27
- data/README.md +32 -4
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/lib/papercall.rb +1 -0
- data/lib/papercall/analysis.rb +113 -74
- data/lib/papercall/configuration.rb +11 -0
- data/lib/papercall/core.rb +38 -25
- data/lib/papercall/file_fetcher.rb +11 -8
- data/lib/papercall/models/feedback.rb +15 -0
- data/lib/papercall/models/presenter_profile.rb +16 -0
- data/lib/papercall/models/presenter_profle.rb +0 -0
- data/lib/papercall/models/rating.rb +15 -0
- data/lib/papercall/models/submission.rb +78 -0
- data/lib/papercall/models/talk.rb +13 -0
- data/lib/papercall/models/user.rb +10 -0
- data/lib/papercall/rest_fetcher.rb +29 -19
- data/lib/papercall/version.rb +1 -1
- data/papercall.gemspec +10 -10
- metadata +33 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c01ac69e7a39cce23602d48764e3973e8dfe4df1b6b9c78c49ef139a90a84ae8
|
4
|
+
data.tar.gz: 1a860bcc822007737378bab9f97877acc07e443188b3f2ee345e77e1b84a46b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ba6af36d0f36b604069bbb4012dc5a33177fb2dfe1e2a530ef824395a82967c7285f5349c28d0844133d5aadd7d330b9ce48ed6327e5f317fedaa201bf9b92b
|
7
|
+
data.tar.gz: 04d62a8dc0acee34c079920467623276a16d60c6d8976dab00887bf7ef1805dd0fdee55c41372510ce1ef5208155e8c7d86cbaeaafcbd27c248b36ffc9c57fa7
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|
55
55
|
## Enforcement
|
56
56
|
|
57
57
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
-
reported by contacting the project team at joe@
|
58
|
+
reported by contacting the project team at joe@equinor.com. All
|
59
59
|
complaints will be reviewed and investigated and will result in a response that
|
60
60
|
is deemed necessary and appropriate to the circumstances. The project team is
|
61
61
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
data/Guardfile
CHANGED
@@ -39,32 +39,8 @@ guard :rspec, cmd: 'bundle exec rspec' do
|
|
39
39
|
# Ruby files
|
40
40
|
ruby = dsl.ruby
|
41
41
|
dsl.watch_spec_files_for(ruby.lib_files)
|
42
|
+
#watch(/^lib\/(.+)\.rb$/) { | m | "spec/#{m[1]}_test.rb" }
|
43
|
+
#watch(/^lib\/papercall\/(.+)\.rb$/) { | m | "spec/#{m[1]}_test.rb" }
|
44
|
+
#watch(/^lib\/papercall\/models\/(.+)\.rb$/) { | m | "spec/#{m[1]}_test.rb" }
|
42
45
|
|
43
|
-
# Rails files
|
44
|
-
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
45
|
-
dsl.watch_spec_files_for(rails.app_files)
|
46
|
-
dsl.watch_spec_files_for(rails.views)
|
47
|
-
|
48
|
-
watch(rails.controllers) do |m|
|
49
|
-
[
|
50
|
-
rspec.spec.call("routing/#{m[1]}_routing"),
|
51
|
-
rspec.spec.call("controllers/#{m[1]}_controller"),
|
52
|
-
rspec.spec.call("acceptance/#{m[1]}")
|
53
|
-
]
|
54
|
-
end
|
55
|
-
|
56
|
-
# Rails config changes
|
57
|
-
watch(rails.spec_helper) { rspec.spec_dir }
|
58
|
-
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
59
|
-
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
60
|
-
|
61
|
-
# Capybara features specs
|
62
|
-
watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
|
63
|
-
watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
|
64
|
-
|
65
|
-
# Turnip features and steps
|
66
|
-
watch(%r{^spec/acceptance/(.+)\.feature$})
|
67
|
-
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
68
|
-
Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance'
|
69
|
-
end
|
70
46
|
end
|
data/README.md
CHANGED
@@ -31,26 +31,54 @@ The following code will fetch all the submissions from your event and print a su
|
|
31
31
|
```ruby
|
32
32
|
require 'papercall'
|
33
33
|
|
34
|
-
Papercall.
|
34
|
+
Papercall.configure do |config|
|
35
|
+
config.API_KEY = "<your api key>"
|
36
|
+
end
|
37
|
+
Papercall.fetch(:from_papercall, :submitted, :accepted, :rejected, :waitlist, :declined)
|
35
38
|
Papercall.summary
|
36
39
|
```
|
37
40
|
|
38
41
|
The Papercall gem also allows you to fetch individual states, or just the ones you care about:
|
39
42
|
|
40
43
|
```ruby
|
41
|
-
Papercall.
|
44
|
+
Papercall.configure do |config|
|
45
|
+
config.API_KEY = "<your api key>"
|
46
|
+
end
|
47
|
+
Papercall.fetch(:from_papercall, :submitted, :accepted)
|
42
48
|
```
|
43
49
|
or
|
44
50
|
```ruby
|
45
|
-
Papercall.
|
51
|
+
Papercall.configure do |config|
|
52
|
+
config.API_KEY = "<your api key>"
|
53
|
+
end
|
54
|
+
Papercall.fetch(:from_papercall, :rejected, :declined, :waitelist)
|
46
55
|
```
|
47
56
|
The order does not matter.
|
48
57
|
|
49
58
|
You can also use this shortcut if you want to fetch all:
|
50
59
|
```ruby
|
51
|
-
Papercall.
|
60
|
+
Papercall.configure do |config|
|
61
|
+
config.API_KEY = "<your api key>"
|
62
|
+
end
|
63
|
+
Papercall.fetch(:from_papercall, :all)
|
52
64
|
```
|
53
65
|
|
66
|
+
## Other configuration options
|
67
|
+
You can configure the following attributes:
|
68
|
+
* API key
|
69
|
+
* Turning output on or off (default is on)
|
70
|
+
* Input file - used for reading from submissions from file (default: submissions.json)
|
71
|
+
* Number of threads - number of parallel threads used to fetch ratings and feedback (default 150)
|
72
|
+
|
73
|
+
Example:
|
74
|
+
```ruby
|
75
|
+
Papercall.configure do |config|
|
76
|
+
config.API_KEY = "<your api key>"
|
77
|
+
config.output = false
|
78
|
+
config.threads = 200
|
79
|
+
config.input_file = "my_subscription.txt"
|
80
|
+
end
|
81
|
+
```
|
54
82
|
|
55
83
|
## Development
|
56
84
|
|
data/bin/console
CHANGED
File without changes
|
data/bin/setup
CHANGED
File without changes
|
data/lib/papercall.rb
CHANGED
data/lib/papercall/analysis.rb
CHANGED
@@ -1,103 +1,142 @@
|
|
1
1
|
module Papercall
|
2
2
|
class Analysis
|
3
|
+
attr_reader :submissions,
|
4
|
+
:reviewers,
|
5
|
+
:talks_without_reviews,
|
6
|
+
:talks_missing_reviews,
|
7
|
+
:talks_with_many_reviews,
|
8
|
+
:talks_without_feedback,
|
9
|
+
:highly_rated,
|
10
|
+
:low_rated,
|
11
|
+
:maybe,
|
12
|
+
:accepted,
|
13
|
+
:waitlisted,
|
14
|
+
:rejected,
|
15
|
+
:confirmed,
|
16
|
+
:summary
|
17
|
+
|
3
18
|
def initialize submissions
|
4
|
-
@
|
5
|
-
@
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
19
|
+
@output = Papercall.configuration.output
|
20
|
+
@submissions = submissions
|
21
|
+
@reviewers = {}
|
22
|
+
@talks_without_reviews = []
|
23
|
+
@talks_missing_reviews = []
|
24
|
+
@talks_with_many_reviews = []
|
25
|
+
@talks_without_feedback = []
|
26
|
+
@highly_rated = []
|
27
|
+
@low_rated = []
|
28
|
+
@maybe = []
|
29
|
+
@accepted = []
|
30
|
+
@waitlisted = []
|
31
|
+
@rejected = []
|
32
|
+
@confirmed = []
|
33
|
+
analyze
|
18
34
|
end
|
19
35
|
|
20
|
-
def
|
21
|
-
|
22
|
-
print 'Performing analysis...'
|
23
|
-
@analysis['submissions'].each do |submission|
|
24
|
-
submission['ratings'].each do |rating|
|
25
|
-
if !(@analysis['reviewers'].include? rating['user']['name'])
|
26
|
-
@analysis['reviewers'][rating['user']['name']] = [{ id: rating['submission_id'] }]
|
27
|
-
else
|
28
|
-
@analysis['reviewers'][rating['user']['name']] << { id: rating['submission_id'] }
|
29
|
-
end
|
30
|
-
end
|
31
|
-
@analysis['talksWithoutReviews'] << { id: submission['id'], submission: submission } if submission['ratings'].empty?
|
32
|
-
@analysis['talksWithFourOrMoreReviews'] << { id: submission['id'], submission: submission } if submission['ratings'].size >= 4
|
33
|
-
@analysis['talksWithLessThanThreeReviews'] << { id: submission['id'], submission: submission } if submission['ratings'].size < 3
|
34
|
-
@analysis['talksWithoutFeedback'] << { id: submission['id'], submission: submission } if submission['feedback'].empty?
|
35
|
-
@analysis['highlyRated'] << { id: submission['id'], submission: submission } if highly_rated? submission
|
36
|
-
@analysis['lowRated'] << { id: submission['id'], submission: submission } if low_rated? submission
|
37
|
-
@analysis['maybe'] << { id: submission['id'], submission: submission } if maybe? submission
|
38
|
-
@analysis['accepted'] << { id: submission['id'], submission: submission } if accepted? submission
|
39
|
-
@analysis['waitlist'] << { id: submission['id'], submission: submission } if waitlisted? submission
|
40
|
-
@analysis['rejected'] << { id: submission['id'], submission: submission } if rejected? submission
|
41
|
-
@analysis['confirmed'] << { id: submission['id'], submission: submission } if confirmed? submission
|
42
|
-
end
|
43
|
-
@analysis['summary'] = summary
|
44
|
-
puts "finished in #{Time.now - start_time} seconds."
|
45
|
-
@analysis
|
36
|
+
def number_of_submissions
|
37
|
+
@submissions.size
|
46
38
|
end
|
47
39
|
|
48
|
-
|
40
|
+
def number_of_active_reviewers
|
41
|
+
@reviewers.size
|
42
|
+
end
|
43
|
+
|
44
|
+
def number_without_feedback
|
45
|
+
@talks_without_feedback.size
|
46
|
+
end
|
47
|
+
|
48
|
+
def number_completed
|
49
|
+
@submissions.size - @talks_missing_reviews.size
|
50
|
+
end
|
51
|
+
|
52
|
+
def number_of_highly_rated
|
53
|
+
@highly_rated.size
|
54
|
+
end
|
49
55
|
|
50
|
-
def
|
51
|
-
|
56
|
+
def number_of_low_rated
|
57
|
+
@low_rated.size
|
52
58
|
end
|
53
59
|
|
54
|
-
def
|
55
|
-
|
60
|
+
def number_of_maybes
|
61
|
+
@maybe.size
|
56
62
|
end
|
57
63
|
|
58
|
-
def
|
59
|
-
|
60
|
-
!rejected?(submission) &&
|
61
|
-
review_complete?(submission)
|
64
|
+
def number_with_few_reviews
|
65
|
+
@talks_missing_reviews.size
|
62
66
|
end
|
63
67
|
|
64
|
-
def
|
65
|
-
|
68
|
+
def number_with_many_reviews
|
69
|
+
@talks_with_many_reviews.size
|
66
70
|
end
|
67
71
|
|
68
|
-
def
|
69
|
-
|
72
|
+
def number_without_reviews
|
73
|
+
@talks_without_reviews.size
|
70
74
|
end
|
71
75
|
|
72
|
-
def
|
73
|
-
|
76
|
+
def number_accepted
|
77
|
+
@accepted.size
|
74
78
|
end
|
75
79
|
|
76
|
-
def
|
77
|
-
|
80
|
+
def number_of_waitlisted
|
81
|
+
@waitlisted.size
|
78
82
|
end
|
79
83
|
|
80
|
-
def
|
81
|
-
|
84
|
+
def number_rejected
|
85
|
+
@rejected.size
|
82
86
|
end
|
83
87
|
|
84
|
-
def
|
88
|
+
def number_confirmed
|
89
|
+
@confirmed.size
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def analyze
|
96
|
+
start_time = Time.now
|
97
|
+
print 'Performing analysis...' if @output
|
98
|
+
@submissions.each do |submission|
|
99
|
+
submission.ratings.each do |rating|
|
100
|
+
if !(@reviewers.include? rating.user.name)
|
101
|
+
@reviewers[rating.user.name] = [{ id: rating.submission_id }]
|
102
|
+
else
|
103
|
+
@reviewers[rating.user.name] << { id: rating.submission_id }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
@talks_without_reviews << { id: submission.id, submission: submission } if submission.no_reviews?
|
107
|
+
@talks_with_many_reviews << { id: submission.id, submission: submission } if submission.too_many_reviews?
|
108
|
+
@talks_missing_reviews << {id: submission.id, submission: submission} unless submission.enough_reviews?
|
109
|
+
@talks_without_feedback << { id: submission.id, submission: submission } if submission.no_feedback?
|
110
|
+
@highly_rated << { id: submission.id, submission: submission } if submission.highly_rated?
|
111
|
+
@low_rated << { id: submission.id, submission: submission } if submission.low_rated?
|
112
|
+
@maybe << { id: submission.id, submission: submission } if submission.maybe?
|
113
|
+
@accepted << { id: submission.id, submission: submission } if submission.accepted?
|
114
|
+
@waitlisted << { id: submission.id, submission: submission } if submission.waitlisted?
|
115
|
+
@rejected << { id: submission.id, submission: submission } if submission.rejected?
|
116
|
+
@confirmed << { id: submission.id, submission: submission } if submission.confirmed?
|
117
|
+
end
|
118
|
+
@summary = build_summary
|
119
|
+
puts "finished in #{Time.now - start_time} seconds." if @output
|
120
|
+
end
|
121
|
+
|
122
|
+
def build_summary
|
85
123
|
summary = {}
|
86
|
-
summary['numSubmissions'] = @
|
87
|
-
summary['numActiveReviewers'] = @
|
88
|
-
summary['numWithoutFeedback'] = @
|
89
|
-
summary['numCompleted'] = @
|
90
|
-
summary['numHighlyRated'] = @
|
91
|
-
summary['numLowRated'] = @
|
92
|
-
summary['numMaybe'] = @
|
93
|
-
summary['numLessThanThreeReviews'] = @
|
94
|
-
summary['numWithFourOrMoreReviews'] = @
|
95
|
-
summary['numWithoutReviews'] = @
|
96
|
-
summary['numAccepted'] = @
|
97
|
-
summary['numWaitlisted'] = @
|
98
|
-
summary['numRejected'] = @
|
99
|
-
summary['numConfirmed'] = @
|
124
|
+
summary['numSubmissions'] = @submissions.size
|
125
|
+
summary['numActiveReviewers'] = @reviewers.size
|
126
|
+
summary['numWithoutFeedback'] = @talks_without_feedback.size
|
127
|
+
summary['numCompleted'] = @submissions.size - @talks_missing_reviews.size
|
128
|
+
summary['numHighlyRated'] = @highly_rated.size
|
129
|
+
summary['numLowRated'] = @low_rated.size
|
130
|
+
summary['numMaybe'] = @maybe.size
|
131
|
+
summary['numLessThanThreeReviews'] = @talks_missing_reviews.size
|
132
|
+
summary['numWithFourOrMoreReviews'] = @talks_with_many_reviews.size
|
133
|
+
summary['numWithoutReviews'] = @talks_without_reviews.size
|
134
|
+
summary['numAccepted'] = @accepted.size
|
135
|
+
summary['numWaitlisted'] = @waitlisted.size
|
136
|
+
summary['numRejected'] = @rejected.size
|
137
|
+
summary['numConfirmed'] = @confirmed.size
|
100
138
|
summary
|
101
139
|
end
|
140
|
+
|
102
141
|
end
|
103
142
|
end
|
data/lib/papercall/core.rb
CHANGED
@@ -2,16 +2,27 @@
|
|
2
2
|
# Also providing some analytics
|
3
3
|
module Papercall
|
4
4
|
METHOD_REGEX = /(.*)_talks$/
|
5
|
+
class << self
|
6
|
+
attr_writer :configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.configuration
|
10
|
+
@configuration ||= Configuration.new
|
11
|
+
end
|
5
12
|
|
6
|
-
def self.
|
13
|
+
def self.configure
|
14
|
+
yield(configuration)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.fetch(from, *states)
|
7
18
|
if from == :from_file
|
8
|
-
@submissions = Papercall::FileFetcher.new
|
19
|
+
@submissions = Papercall::FileFetcher.new
|
9
20
|
elsif from == :from_papercall
|
10
|
-
@submissions = Papercall::RestFetcher.new
|
21
|
+
@submissions = Papercall::RestFetcher.new
|
11
22
|
end
|
12
23
|
@submissions.fetch(states)
|
24
|
+
#puts @submissions.analysis
|
13
25
|
@analysis = Papercall::Analysis.new(@submissions.analysis)
|
14
|
-
@analysis = @analysis.analyze
|
15
26
|
end
|
16
27
|
|
17
28
|
def self.all
|
@@ -20,7 +31,7 @@ module Papercall
|
|
20
31
|
|
21
32
|
def self.save_to_file(filename)
|
22
33
|
ff = File.open(filename, 'w') { |f| f.write(@submissions.all.to_json) }
|
23
|
-
puts "All submissions written to file #{filename}." if ff
|
34
|
+
puts "All submissions written to file #{filename}." if ff && configuration.output
|
24
35
|
end
|
25
36
|
|
26
37
|
def self.number_of_submissions
|
@@ -29,20 +40,20 @@ module Papercall
|
|
29
40
|
|
30
41
|
def self.confirmed_talks
|
31
42
|
@submissions.accepted.select do |s|
|
32
|
-
s
|
43
|
+
s.confirmed?
|
33
44
|
end
|
34
45
|
end
|
35
46
|
|
36
47
|
def self.active_reviewers
|
37
|
-
@analysis
|
48
|
+
@analysis.reviewers
|
38
49
|
end
|
39
50
|
|
40
51
|
def self.submissions_without_feedback
|
41
|
-
@analysis
|
52
|
+
@analysis.talks_without_feedback
|
42
53
|
end
|
43
54
|
|
44
55
|
def self.submissions_with_enough_reviews
|
45
|
-
@analysis
|
56
|
+
@analysis.submissions - @analysis.talks_missing_reviews
|
46
57
|
end
|
47
58
|
|
48
59
|
def self.analysis
|
@@ -50,22 +61,24 @@ module Papercall
|
|
50
61
|
end
|
51
62
|
|
52
63
|
def self.summary
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
a = @analysis
|
65
|
+
if configuration.output
|
66
|
+
puts "Number of submissions: #{a.number_of_submissions}"
|
67
|
+
puts "Number of active reviewers: #{a.number_of_active_reviewers}"
|
68
|
+
puts "Number of submitted talks without feedback: #{a.number_without_feedback}"
|
69
|
+
puts "Number of talks with three or more reviews: #{a.number_completed}"
|
70
|
+
puts "Number of highly rated talks: #{a.number_of_highly_rated}"
|
71
|
+
puts "Number of low rated talks: #{a.number_of_low_rated}"
|
72
|
+
puts "Number of middle rated talks: #{a.number_of_maybes}"
|
73
|
+
puts "Number of talks with less than three reviews: #{a.number_with_few_reviews}"
|
74
|
+
puts "Number of talks with four or more reviews: #{a.number_with_many_reviews}"
|
75
|
+
puts "Number of talks without reviews: #{a.number_without_reviews}"
|
76
|
+
puts "Number of accepted talks: #{a.number_accepted}"
|
77
|
+
puts "Number of waitlisted talks: #{a.number_of_waitlisted}"
|
78
|
+
puts "Number of rejected talks: #{a.number_rejected}"
|
79
|
+
puts "Number of confirmed talks: #{a.number_confirmed}"
|
80
|
+
end
|
81
|
+
a
|
69
82
|
end
|
70
83
|
|
71
84
|
def self.respond_to_missing?(method_name, _include_private = false)
|
@@ -1,12 +1,15 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'papercall/models/submission'
|
3
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
4
|
|
3
5
|
module Papercall
|
4
6
|
# Fetches submissions from file.
|
5
7
|
# Params:
|
6
8
|
# +filename+:: File with submissions. JSON format.
|
7
9
|
class FileFetcher < Fetcher
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
+
def initialize()
|
11
|
+
@output = Papercall.configuration.output
|
12
|
+
@filename = Papercall.configuration.input_file
|
10
13
|
@submitted = []
|
11
14
|
@accepted = []
|
12
15
|
@rejected = []
|
@@ -16,12 +19,12 @@ module Papercall
|
|
16
19
|
|
17
20
|
def fetch(_)
|
18
21
|
file = File.new(@filename, 'r')
|
19
|
-
puts
|
20
|
-
submissions = JSON.parse
|
21
|
-
@submitted = submissions[
|
22
|
-
@accepted = submissions[
|
23
|
-
@rejected = submissions[
|
24
|
-
@waitlist = submissions[
|
22
|
+
puts 'Reading from file (#{file.path})...' if @output
|
23
|
+
submissions = JSON.parse(file.read).with_indifferent_access if file
|
24
|
+
@submitted = submissions[:submitted].map {|s| Submission.new(s)}
|
25
|
+
@accepted = submissions[:accepted].map {|s| Submission.new(s)}
|
26
|
+
@rejected = submissions[:rejected].map {|s| Submission.new(s)}
|
27
|
+
@waitlist = submissions[:waitlist].map {|s| Submission.new(s)}
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'user'
|
2
|
+
|
3
|
+
class Feedback
|
4
|
+
attr_reader :id, :submission_id, :talk_id, :user, :body, :created_at, :updated_at
|
5
|
+
|
6
|
+
def initialize(json_hash)
|
7
|
+
@id = json_hash[:id]
|
8
|
+
@submission_id = json_hash[:submission_id]
|
9
|
+
@talk_id = json_hash[:talk_id]
|
10
|
+
@user = User.new(json_hash[:user])
|
11
|
+
@body = json_hash[:body]
|
12
|
+
@created_at = Time.parse(json_hash[:created_at])
|
13
|
+
@updated_at = Time.parse(json_hash[:updated_at])
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
class PresenterProfile
|
3
|
+
attr_reader :name, :bio, :twitter, :company, :url, :shirt_size, :email, :location, :avatar
|
4
|
+
|
5
|
+
def initialize(json_hash = {})
|
6
|
+
@name = json_hash[:name]
|
7
|
+
@bio = json_hash[:bio]
|
8
|
+
@twitter = json_hash[:twitter]
|
9
|
+
@company = json_hash[:company]
|
10
|
+
@url = json_hash[:url]
|
11
|
+
@shirt_size = json_hash[:shirt_size]
|
12
|
+
@email = json_hash[:email]
|
13
|
+
@location = json_hash[:location]
|
14
|
+
@avatar = json_hash[:avatar]
|
15
|
+
end
|
16
|
+
end
|
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'user'
|
2
|
+
|
3
|
+
class Rating
|
4
|
+
attr_reader :id, :submission_id, :value, :comments, :created_at, :updated_at, :user
|
5
|
+
|
6
|
+
def initialize(json_hash)
|
7
|
+
@id = json_hash[:id]
|
8
|
+
@submission_id = json_hash[:submission_id]
|
9
|
+
@value = json_hash[:value]
|
10
|
+
@comments = json_hash[:comments]
|
11
|
+
@created_at = Time.parse(json_hash[:created_at])
|
12
|
+
@updated_at = Time.parse(json_hash[:updated_at])
|
13
|
+
@user = User.new(json_hash[:user])
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative 'presenter_profile'
|
2
|
+
require_relative 'talk'
|
3
|
+
|
4
|
+
class Submission
|
5
|
+
attr_reader :id, :state, :confirmed, :created_at, :updated_at, :additional_info, :rating, :trust, :tags,
|
6
|
+
:co_presenter_profiles, :presenter_profile, :talk, :cfp_additional_answers
|
7
|
+
attr_accessor :ratings, :feedback
|
8
|
+
|
9
|
+
def initialize(json_hash)
|
10
|
+
@id = json_hash[:id]
|
11
|
+
@state = json_hash[:state]
|
12
|
+
@confirmed = json_hash[:confirmed]
|
13
|
+
@created_at = Time.parse(json_hash[:created_at])
|
14
|
+
@updated_at = Time.parse(json_hash[:updated_at])
|
15
|
+
@additional_info = json_hash[:additional_info]
|
16
|
+
@rating = json_hash[:rating]
|
17
|
+
@trust = json_hash[:trust]
|
18
|
+
@tags = json_hash[:tags]
|
19
|
+
@co_presenter_profiles = json_hash[:co_presenter_profiles]
|
20
|
+
@presenter_profile = PresenterProfile.new(json_hash[:profile])
|
21
|
+
@talk = Talk.new(json_hash[:talk])
|
22
|
+
@cfp_additional_answers = json_hash[:cfp_additional_question_answers]
|
23
|
+
@ratings = []
|
24
|
+
@feedback = []
|
25
|
+
end
|
26
|
+
|
27
|
+
def no_reviews?
|
28
|
+
@ratings.empty?
|
29
|
+
end
|
30
|
+
|
31
|
+
def enough_reviews?
|
32
|
+
@ratings.size >= 3
|
33
|
+
end
|
34
|
+
|
35
|
+
def too_many_reviews?
|
36
|
+
@ratings.size >= 4
|
37
|
+
end
|
38
|
+
|
39
|
+
def highly_rated?
|
40
|
+
@rating >= 75 && enough_reviews?
|
41
|
+
end
|
42
|
+
|
43
|
+
def low_rated?
|
44
|
+
@rating <= 25 && enough_reviews?
|
45
|
+
end
|
46
|
+
|
47
|
+
def maybe?
|
48
|
+
!accepted? && !rejected? && enough_reviews?
|
49
|
+
end
|
50
|
+
|
51
|
+
def accepted?
|
52
|
+
@state == 'accepted'
|
53
|
+
end
|
54
|
+
|
55
|
+
def rejected?
|
56
|
+
@state == 'rejected'
|
57
|
+
end
|
58
|
+
|
59
|
+
def waitlisted?
|
60
|
+
@state == 'waitlist'
|
61
|
+
end
|
62
|
+
|
63
|
+
def confirmed?
|
64
|
+
accepted? && @confirmed == true
|
65
|
+
end
|
66
|
+
|
67
|
+
def no_feedback?
|
68
|
+
@feedback.empty?
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
puts "Submission: #{@id}, #{@talk.title}, #{@presenter_profile.name}. Number of reviews: #{@ratings.size}. Number of feedback: #{@feedback.size}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_json
|
76
|
+
this.to_h.to_json
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
class Talk
|
3
|
+
attr_reader :title, :description, :notes, :abstract, :audience_level, :talk_format
|
4
|
+
|
5
|
+
def initialize(json_hash)
|
6
|
+
@title = json_hash[:title]
|
7
|
+
@description = json_hash[:description]
|
8
|
+
@notes = json_hash[:notes]
|
9
|
+
@abstract = json_hash[:abstract]
|
10
|
+
@audience_level = json_hash[:audience_level]
|
11
|
+
@talk_format = json_hash[:talk_format]
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'rest-client'
|
3
3
|
require 'parallel'
|
4
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
5
|
+
require 'papercall/models/submission'
|
6
|
+
require 'papercall/models/rating'
|
7
|
+
require 'papercall/models/feedback'
|
4
8
|
|
5
9
|
module Papercall
|
6
10
|
# Fetches submissions from Papercall REST API
|
@@ -8,7 +12,10 @@ module Papercall
|
|
8
12
|
class RestFetcher < Fetcher
|
9
13
|
SUBMISSIONS_URL = 'https://www.papercall.io/api/v1/submissions'.freeze
|
10
14
|
|
11
|
-
def initialize(
|
15
|
+
def initialize()
|
16
|
+
@output = Papercall.configuration.output
|
17
|
+
api_key = Papercall.configuration.API_KEY
|
18
|
+
raise ArgumentError, 'Missing API_KEY for access to Papercall. Please refer to documentation for instructions on setting this value.' unless api_key
|
12
19
|
@auth_hash = { Authorization: api_key }
|
13
20
|
@submitted = []
|
14
21
|
@accepted = []
|
@@ -27,7 +34,7 @@ module Papercall
|
|
27
34
|
url: papercall_url,
|
28
35
|
headers: @auth_hash) # :timeout => 120
|
29
36
|
if raw_results
|
30
|
-
JSON.parse
|
37
|
+
JSON.parse(raw_results).map {|r| r.with_indifferent_access}
|
31
38
|
else
|
32
39
|
[]
|
33
40
|
end
|
@@ -38,9 +45,11 @@ module Papercall
|
|
38
45
|
states.flatten.each do |state|
|
39
46
|
next unless state
|
40
47
|
start_time = Time.now
|
41
|
-
print "Fetching #{state} submissions from PaperCall API..."
|
42
|
-
|
43
|
-
|
48
|
+
print "Fetching #{state} submissions from PaperCall API..." if @output
|
49
|
+
submissions = papercall(submission_url(state.to_s))
|
50
|
+
instance_variable_set("@#{state}_raw", submissions)
|
51
|
+
instance_variable_set("@#{state}", submissions.map {|s| Submission.new(s)})
|
52
|
+
puts "finished in #{Time.now - start_time} seconds." if @output
|
44
53
|
end
|
45
54
|
fetch_ratings
|
46
55
|
fetch_feedback
|
@@ -48,29 +57,30 @@ module Papercall
|
|
48
57
|
|
49
58
|
def fetch_ratings
|
50
59
|
start_time = Time.now
|
51
|
-
print 'Fetching ratings for all submissions from Papercall API...'
|
60
|
+
print 'Fetching ratings for all submissions from Papercall API...' if @output
|
52
61
|
|
53
|
-
Parallel.each(analysis, in_threads:
|
54
|
-
|
55
|
-
ratings_url = "#{SUBMISSIONS_URL}/#{submission
|
56
|
-
|
62
|
+
Parallel.each(analysis, in_threads: 128) do |submission|
|
63
|
+
if submission.ratings.empty?
|
64
|
+
ratings_url = "#{SUBMISSIONS_URL}/#{submission.id}/ratings"
|
65
|
+
ratings = papercall(ratings_url).map {|r| Rating.new(r)}
|
66
|
+
submission.ratings = ratings
|
57
67
|
end
|
58
|
-
submission
|
68
|
+
#submission.ratings = [] unless submission.ratings
|
59
69
|
end
|
60
|
-
puts "finished in #{Time.now - start_time} seconds."
|
70
|
+
puts "finished in #{Time.now - start_time} seconds." if @output
|
61
71
|
end
|
62
72
|
|
63
73
|
def fetch_feedback
|
64
74
|
start_time = Time.now
|
65
|
-
print 'Fetching feedback for all submissions from Papercall API...'
|
66
|
-
Parallel.each(analysis, in_threads:
|
67
|
-
|
68
|
-
feedback_url = "#{SUBMISSIONS_URL}/#{submission
|
69
|
-
submission
|
75
|
+
print 'Fetching feedback for all submissions from Papercall API...' if @output
|
76
|
+
Parallel.each(analysis, in_threads: 128) do |submission|
|
77
|
+
if submission.feedback.empty?
|
78
|
+
feedback_url = "#{SUBMISSIONS_URL}/#{submission.id}/feedback"
|
79
|
+
submission.feedback = papercall(feedback_url).map {|f| Feedback.new(f)}
|
70
80
|
end
|
71
|
-
submission
|
81
|
+
#submission.feedback = [] unless submission.feedback
|
72
82
|
end
|
73
|
-
puts "finished in #{Time.now - start_time} seconds."
|
83
|
+
puts "finished in #{Time.now - start_time} seconds." if @output
|
74
84
|
end
|
75
85
|
end
|
76
86
|
end
|
data/lib/papercall/version.rb
CHANGED
data/papercall.gemspec
CHANGED
@@ -21,17 +21,17 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_development_dependency "bundler", "~> 1.
|
25
|
-
spec.add_development_dependency "rake", "~>
|
26
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
-
spec.add_development_dependency "guard", "~> 2.
|
24
|
+
spec.add_development_dependency "bundler", "~> 2.1.4"
|
25
|
+
spec.add_development_dependency "rake", "~> 13.0.1"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.9.0"
|
27
|
+
spec.add_development_dependency "guard", "~> 2.16.2"
|
28
28
|
spec.add_development_dependency "guard-rspec", "~> 4.7", ">= 4.7.3"
|
29
|
-
spec.add_development_dependency "pry", "~> 0.
|
30
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
29
|
+
spec.add_development_dependency "pry", "~> 0.13.1"
|
30
|
+
spec.add_development_dependency "rubocop", "~> 0.90.0"
|
31
31
|
|
32
|
-
spec.add_dependency "json", "~> 2.1"
|
33
|
-
spec.add_dependency "rest-client", "~> 2.
|
34
|
-
spec.add_dependency "activesupport", "~>
|
35
|
-
spec.add_dependency "i18n", "~>
|
32
|
+
spec.add_dependency "json", "~> 2.3.1"
|
33
|
+
spec.add_dependency "rest-client", "~> 2.1", ">= 2.1.0"
|
34
|
+
spec.add_dependency "activesupport", "~> 6.0"
|
35
|
+
spec.add_dependency "i18n", "~> 1.8.5"
|
36
36
|
spec.add_dependency "parallel", "~> 1.12.1"
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: papercall
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jørn Ølmheim
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.1.4
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.1.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 13.0.1
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 13.0.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 3.9.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 3.9.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: guard
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 2.16.2
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 2.16.2
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: guard-rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,90 +92,90 @@ dependencies:
|
|
92
92
|
requirements:
|
93
93
|
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: 0.
|
95
|
+
version: 0.13.1
|
96
96
|
type: :development
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: 0.
|
102
|
+
version: 0.13.1
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: rubocop
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - "~>"
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 0.
|
109
|
+
version: 0.90.0
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
112
|
version_requirements: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
114
|
- - "~>"
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version: 0.
|
116
|
+
version: 0.90.0
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
118
|
name: json
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
121
|
- - "~>"
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
123
|
+
version: 2.3.1
|
124
124
|
type: :runtime
|
125
125
|
prerelease: false
|
126
126
|
version_requirements: !ruby/object:Gem::Requirement
|
127
127
|
requirements:
|
128
128
|
- - "~>"
|
129
129
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
130
|
+
version: 2.3.1
|
131
131
|
- !ruby/object:Gem::Dependency
|
132
132
|
name: rest-client
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
135
|
- - "~>"
|
136
136
|
- !ruby/object:Gem::Version
|
137
|
-
version: '2.
|
137
|
+
version: '2.1'
|
138
138
|
- - ">="
|
139
139
|
- !ruby/object:Gem::Version
|
140
|
-
version: 2.0
|
140
|
+
version: 2.1.0
|
141
141
|
type: :runtime
|
142
142
|
prerelease: false
|
143
143
|
version_requirements: !ruby/object:Gem::Requirement
|
144
144
|
requirements:
|
145
145
|
- - "~>"
|
146
146
|
- !ruby/object:Gem::Version
|
147
|
-
version: '2.
|
147
|
+
version: '2.1'
|
148
148
|
- - ">="
|
149
149
|
- !ruby/object:Gem::Version
|
150
|
-
version: 2.0
|
150
|
+
version: 2.1.0
|
151
151
|
- !ruby/object:Gem::Dependency
|
152
152
|
name: activesupport
|
153
153
|
requirement: !ruby/object:Gem::Requirement
|
154
154
|
requirements:
|
155
155
|
- - "~>"
|
156
156
|
- !ruby/object:Gem::Version
|
157
|
-
version: '
|
157
|
+
version: '6.0'
|
158
158
|
type: :runtime
|
159
159
|
prerelease: false
|
160
160
|
version_requirements: !ruby/object:Gem::Requirement
|
161
161
|
requirements:
|
162
162
|
- - "~>"
|
163
163
|
- !ruby/object:Gem::Version
|
164
|
-
version: '
|
164
|
+
version: '6.0'
|
165
165
|
- !ruby/object:Gem::Dependency
|
166
166
|
name: i18n
|
167
167
|
requirement: !ruby/object:Gem::Requirement
|
168
168
|
requirements:
|
169
169
|
- - "~>"
|
170
170
|
- !ruby/object:Gem::Version
|
171
|
-
version:
|
171
|
+
version: 1.8.5
|
172
172
|
type: :runtime
|
173
173
|
prerelease: false
|
174
174
|
version_requirements: !ruby/object:Gem::Requirement
|
175
175
|
requirements:
|
176
176
|
- - "~>"
|
177
177
|
- !ruby/object:Gem::Version
|
178
|
-
version:
|
178
|
+
version: 1.8.5
|
179
179
|
- !ruby/object:Gem::Dependency
|
180
180
|
name: parallel
|
181
181
|
requirement: !ruby/object:Gem::Requirement
|
@@ -211,9 +211,17 @@ files:
|
|
211
211
|
- bin/setup
|
212
212
|
- lib/papercall.rb
|
213
213
|
- lib/papercall/analysis.rb
|
214
|
+
- lib/papercall/configuration.rb
|
214
215
|
- lib/papercall/core.rb
|
215
216
|
- lib/papercall/fetcher.rb
|
216
217
|
- lib/papercall/file_fetcher.rb
|
218
|
+
- lib/papercall/models/feedback.rb
|
219
|
+
- lib/papercall/models/presenter_profile.rb
|
220
|
+
- lib/papercall/models/presenter_profle.rb
|
221
|
+
- lib/papercall/models/rating.rb
|
222
|
+
- lib/papercall/models/submission.rb
|
223
|
+
- lib/papercall/models/talk.rb
|
224
|
+
- lib/papercall/models/user.rb
|
217
225
|
- lib/papercall/rest_fetcher.rb
|
218
226
|
- lib/papercall/version.rb
|
219
227
|
- papercall.gemspec
|
@@ -238,8 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
238
246
|
- !ruby/object:Gem::Version
|
239
247
|
version: '0'
|
240
248
|
requirements: []
|
241
|
-
|
242
|
-
rubygems_version: 2.6.14
|
249
|
+
rubygems_version: 3.1.2
|
243
250
|
signing_key:
|
244
251
|
specification_version: 4
|
245
252
|
summary: Small client library for the PaperCall API
|