papercall 0.15.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|