duolingo_personal_data 0.1.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 +7 -0
- data/.rubocop.yml +20 -0
- data/.rubocop_todo.yml +50 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +202 -0
- data/README.md +38 -0
- data/Rakefile +22 -0
- data/duolingo_personal_data.gemspec +26 -0
- data/fixtures/TeacherPrivacySettings.csv +2 -0
- data/fixtures/auth_data.csv +6 -0
- data/fixtures/avatar_images.csv +13 -0
- data/fixtures/duolingo-blast-emails.csv +17 -0
- data/fixtures/duolingo-notify-data.csv +4 -0
- data/fixtures/friends-follow.csv +2 -0
- data/fixtures/inventory.csv +5 -0
- data/fixtures/languages.csv +4 -0
- data/fixtures/leaderboards.csv +4 -0
- data/fixtures/profile.csv +13 -0
- data/fixtures/stories-story-completions.csv +4 -0
- data/fixtures/stories.csv +2 -0
- data/lib/duolingo_personal_data/auth_data.rb +39 -0
- data/lib/duolingo_personal_data/avatar_images.rb +24 -0
- data/lib/duolingo_personal_data/blast_emails.rb +84 -0
- data/lib/duolingo_personal_data/friends_follow.rb +47 -0
- data/lib/duolingo_personal_data/inventory.rb +48 -0
- data/lib/duolingo_personal_data/languages.rb +42 -0
- data/lib/duolingo_personal_data/leaderboards.rb +24 -0
- data/lib/duolingo_personal_data/notify_data.rb +33 -0
- data/lib/duolingo_personal_data/profile.rb +67 -0
- data/lib/duolingo_personal_data/stories.rb +29 -0
- data/lib/duolingo_personal_data/story_completions.rb +23 -0
- data/lib/duolingo_personal_data/teacher_privacy_settings.rb +51 -0
- data/lib/duolingo_personal_data/version.rb +3 -0
- data/lib/duolingo_personal_data.rb +17 -0
- data/manifest.scm +3 -0
- data/sig/duolingo_personal_data.rbs +272 -0
- metadata +83 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module DuolingoPersonalData
|
|
2
|
+
class FriendsFollow
|
|
3
|
+
def initialize(csv_path)
|
|
4
|
+
@csv_path = csv_path
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def num_following
|
|
8
|
+
@num_following ||= integer_value_from_property("num_following")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def num_followers
|
|
12
|
+
@num_followers ||= integer_value_from_property("num_followers")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def num_blocking
|
|
16
|
+
@num_blocking ||= integer_value_from_property("num_blocking")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def num_blockers
|
|
20
|
+
@num_blockers ||= integer_value_from_property("num_blockers")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def timestamp_generated
|
|
24
|
+
@timestamp_generated ||= timestamp_value_from_property("timestamp_generated")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def value_from_property(property_name)
|
|
30
|
+
table.first[property_name]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def integer_value_from_property(property_name)
|
|
34
|
+
value = value_from_property(property_name)
|
|
35
|
+
Integer(value)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def timestamp_value_from_property(property_name)
|
|
39
|
+
value = integer_value_from_property(property_name)
|
|
40
|
+
Time.at(value)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def table
|
|
44
|
+
@table ||= CSV.read(@csv_path, headers: true)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
|
|
3
|
+
module DuolingoPersonalData
|
|
4
|
+
InventoryItem = Struct.new(:item_type, :purchase_datetime, :active, :price_in_virtual_currency, :wager_day,
|
|
5
|
+
:payment_processor, :product, :expected_expiration, keyword_init: true)
|
|
6
|
+
|
|
7
|
+
class Inventory
|
|
8
|
+
def initialize(csv_path)
|
|
9
|
+
@csv_path = csv_path
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
extend Forwardable
|
|
13
|
+
def_delegators :items, *(Array.instance_methods - [:object_id])
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def items
|
|
18
|
+
@items ||= table.map do |row|
|
|
19
|
+
item = InventoryItem.new(item_type: row["item_type"],
|
|
20
|
+
purchase_datetime: parse_datetime(row["purchase_datetime"]), active: parse_boolean(row["active"]), payment_processor: row["payment_processor"], product: row["product"])
|
|
21
|
+
price = row["price_in_virtual_currency"]
|
|
22
|
+
item.price_in_virtual_currency = Integer(price) if price
|
|
23
|
+
day = row["wager_day"]
|
|
24
|
+
item.wager_day = Integer(day) if day
|
|
25
|
+
expiration = row["expected_expiration"]
|
|
26
|
+
item.expected_expiration = parse_datetime(expiration) if expiration
|
|
27
|
+
item
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def parse_datetime(str)
|
|
32
|
+
Time.strptime(str, "%Y-%m-%d %T")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def parse_boolean(str)
|
|
36
|
+
case str
|
|
37
|
+
when "false" then false
|
|
38
|
+
when "true" then true
|
|
39
|
+
else
|
|
40
|
+
raise Error, "cannot parse #{str.inspect} as boolean"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def table
|
|
45
|
+
@table ||= CSV.read(@csv_path, headers: true)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
require "csv"
|
|
3
|
+
|
|
4
|
+
module DuolingoPersonalData
|
|
5
|
+
Language = Struct.new(:from_language, :points, :skill_learned, :total_lessons, :days_active, :last_active,
|
|
6
|
+
:prior_proficiency, :subscribed, keyword_init: true)
|
|
7
|
+
class Languages
|
|
8
|
+
def initialize(csv_path)
|
|
9
|
+
@csv_path = csv_path
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
extend Forwardable
|
|
13
|
+
def_delegators :languages, *(Hash.instance_methods - [:object_id])
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def languages
|
|
18
|
+
@languages ||= CSV.read(@csv_path, headers: true).map do |row|
|
|
19
|
+
language = Language.new(from_language: row["from_language"])
|
|
20
|
+
points = row["points"]
|
|
21
|
+
language.points = Integer(points) if points
|
|
22
|
+
skills = row["skills_learned"]
|
|
23
|
+
language.skill_learned = Integer(skills) if skills
|
|
24
|
+
lessons = row["total_lessons"]
|
|
25
|
+
language.total_lessons = Integer(lessons) if lessons
|
|
26
|
+
days = row["days_active"]
|
|
27
|
+
language.days_active = Integer(days) if days
|
|
28
|
+
active = row["last_active"]
|
|
29
|
+
language.last_active = parse_datetime(active) if active
|
|
30
|
+
proficiency = row["prior_proficiency"]
|
|
31
|
+
language.prior_proficiency = Integer(proficiency) if proficiency
|
|
32
|
+
subscribed = row["subscribed"]
|
|
33
|
+
language.subscribed = parse_datetime(subscribed) if subscribed
|
|
34
|
+
{ row["learning_language"] => language }
|
|
35
|
+
end.reduce(&:merge)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def parse_datetime(str)
|
|
39
|
+
Time.strptime(str, "%Y-%m-%d %T")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require "csv"
|
|
2
|
+
require "forwardable"
|
|
3
|
+
|
|
4
|
+
module DuolingoPersonalData
|
|
5
|
+
LeaderboardsEntry = Struct.new(:timestamp, :tier, :score, keyword_init: true)
|
|
6
|
+
|
|
7
|
+
class Leaderboards
|
|
8
|
+
def initialize(csv_path)
|
|
9
|
+
@csv_path = csv_path
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
extend Forwardable
|
|
13
|
+
def_delegators :leaderboards_entries, *(Array.instance_methods - [:object_id])
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def leaderboards_entries
|
|
18
|
+
@leaderboards_entries ||= CSV.read(@csv_path, headers: true).map do |row|
|
|
19
|
+
LeaderboardsEntry.new(timestamp: Time.strptime(row["timestamp"], "%FT%TZ"), tier: Integer(row["tier"]),
|
|
20
|
+
score: Float(row["score"]))
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module DuolingoPersonalData
|
|
4
|
+
class NotifyData
|
|
5
|
+
def initialize(csv_path)
|
|
6
|
+
@csv_path = csv_path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def email
|
|
10
|
+
@email ||= value_from_property("email")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def device_ids
|
|
14
|
+
@device_ids ||= json_value_from_property("device_ids")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def value_from_property(property_name)
|
|
20
|
+
table.find { |row| row["property"] == property_name }["value"]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def json_value_from_property(property_name)
|
|
24
|
+
value = value_from_property(property_name)
|
|
25
|
+
value.gsub!("'", '"')
|
|
26
|
+
JSON.parse(value)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def table
|
|
30
|
+
@table ||= CSV.read(@csv_path, headers: true)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require "csv"
|
|
2
|
+
|
|
3
|
+
module DuolingoPersonalData
|
|
4
|
+
class Profile
|
|
5
|
+
def initialize(csv_path)
|
|
6
|
+
@csv_path = csv_path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def username
|
|
10
|
+
@username ||= value_from_property("username")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def email
|
|
14
|
+
@email ||= value_from_property("email")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def fullname
|
|
18
|
+
@fullname ||= value_from_property("fullname")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def joined_at
|
|
22
|
+
@joined_at ||= datetime_value_from_property("joined_at")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def ui_language
|
|
26
|
+
@ui_language ||= value_from_property("ui_language")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def learning_language
|
|
30
|
+
@learning_language ||= value_from_property("learning_language")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def lingots
|
|
34
|
+
@lingots ||= integer_value_from_property("lingots")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def daily_goal
|
|
38
|
+
@daily_goal ||= integer_value_from_property("daily_goal")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def timezone
|
|
42
|
+
@timezone ||= value_from_property("timezone")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def avatar_url
|
|
46
|
+
@avatar_url ||= value_from_property("avatar_url")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def value_from_property(property_name)
|
|
52
|
+
table.find { |row| row["name"] == property_name }["value"]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def integer_value_from_property(property_name)
|
|
56
|
+
Integer(value_from_property(property_name))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def datetime_value_from_property(property_name)
|
|
60
|
+
Time.strptime(value_from_property(property_name), "%F %T")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def table
|
|
64
|
+
@table ||= CSV.read(@csv_path, headers: true)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module DuolingoPersonalData
|
|
2
|
+
class Stories
|
|
3
|
+
def initialize(csv_path)
|
|
4
|
+
@csv_path = csv_path
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def user_id
|
|
8
|
+
@user_id ||= value_from_property("userId")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def date_of_first_visit_to_stories
|
|
12
|
+
@date_of_first_visit_to_stories ||= datetime_value_from_property("dateOfFirstVisitToStories")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def value_from_property(property_name)
|
|
18
|
+
table.first[property_name]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def datetime_value_from_property(property_name)
|
|
22
|
+
Time.strptime(value_from_property(property_name), "%F %T")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def table
|
|
26
|
+
@table ||= CSV.read(@csv_path, headers: true)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
|
|
3
|
+
module DuolingoPersonalData
|
|
4
|
+
StoryCompletion = Struct.new(:user_id, :story_id, :score, :time, keyword_init: true)
|
|
5
|
+
|
|
6
|
+
class StoryCompletions
|
|
7
|
+
def initialize(csv_path)
|
|
8
|
+
@csv_path = csv_path
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
extend Forwardable
|
|
12
|
+
def_delegators :completions, *(Array.instance_methods - [:object_id])
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def completions
|
|
17
|
+
@completions ||= CSV.read(@csv_path, headers: true).map do |row|
|
|
18
|
+
StoryCompletion.new(user_id: row["userId"], story_id: row["storyId"], score: Integer(row["score"]),
|
|
19
|
+
time: Time.strptime(row["time"], "%F %T"))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module DuolingoPersonalData
|
|
2
|
+
class TeacherPrivacySettings
|
|
3
|
+
def initialize(csv_path)
|
|
4
|
+
@csv_path = csv_path
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def disable_clubs
|
|
8
|
+
@disable_clubs ||= boolean_value_from_property("disable_clubs")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def disable_discussions
|
|
12
|
+
@disable_discussions ||= boolean_value_from_property("disable_discussions")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def disable_events
|
|
16
|
+
@disable_events ||= boolean_value_from_property("disable_events")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def disable_stream
|
|
20
|
+
@disable_stream ||= boolean_value_from_property("disable_stream")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def disable_immersion
|
|
24
|
+
@disable_immersion ||= boolean_value_from_property("disable_immersion")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def disable_mature_words
|
|
28
|
+
@disable_mature_words ||= boolean_value_from_property("disable_mature_words")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def boolean_value_from_property(property_name)
|
|
34
|
+
value = value_from_property(property_name)
|
|
35
|
+
case value
|
|
36
|
+
when "False" then false
|
|
37
|
+
when "True" then true
|
|
38
|
+
else
|
|
39
|
+
raise Error, "cannot interpret #{value.inspect} as boolean"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def value_from_property(property_name)
|
|
44
|
+
table.first[property_name]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def table
|
|
48
|
+
@table ||= CSV.read(@csv_path, headers: true)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative "duolingo_personal_data/version"
|
|
2
|
+
require_relative "duolingo_personal_data/auth_data"
|
|
3
|
+
require_relative "duolingo_personal_data/avatar_images"
|
|
4
|
+
require_relative "duolingo_personal_data/blast_emails"
|
|
5
|
+
require_relative "duolingo_personal_data/notify_data"
|
|
6
|
+
require_relative "duolingo_personal_data/friends_follow"
|
|
7
|
+
require_relative "duolingo_personal_data/inventory"
|
|
8
|
+
require_relative "duolingo_personal_data/languages"
|
|
9
|
+
require_relative "duolingo_personal_data/leaderboards"
|
|
10
|
+
require_relative "duolingo_personal_data/profile"
|
|
11
|
+
require_relative "duolingo_personal_data/stories"
|
|
12
|
+
require_relative "duolingo_personal_data/story_completions"
|
|
13
|
+
require_relative "duolingo_personal_data/teacher_privacy_settings"
|
|
14
|
+
|
|
15
|
+
module DuolingoPersonalData
|
|
16
|
+
class Error < StandardError; end
|
|
17
|
+
end
|
data/manifest.scm
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# TypeProf 0.21.3
|
|
2
|
+
|
|
3
|
+
# Classes
|
|
4
|
+
module DuolingoPersonalData
|
|
5
|
+
VERSION: String
|
|
6
|
+
|
|
7
|
+
class AuthData
|
|
8
|
+
@csv_path: untyped
|
|
9
|
+
@user_account_name: String?
|
|
10
|
+
@table: Array[Array[String?]]
|
|
11
|
+
@email_address: String?
|
|
12
|
+
@last_update_timestamp: String?
|
|
13
|
+
@last_login_attempt_timestamp: String?
|
|
14
|
+
@last_authentication_key_refresh_timestamp: String?
|
|
15
|
+
|
|
16
|
+
def initialize: (untyped csv_path) -> void
|
|
17
|
+
def user_account_name: -> String?
|
|
18
|
+
def email_address: -> String?
|
|
19
|
+
def last_update_timestamp: -> String?
|
|
20
|
+
def last_login_attempt_timestamp: -> String?
|
|
21
|
+
def last_authentication_key_refresh_timestamp: -> String?
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
def value_from_property: (String property_name) -> String?
|
|
25
|
+
def table: -> Array[Array[String?]]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class AvatarImages
|
|
29
|
+
extend Forwardable
|
|
30
|
+
@csv_path: untyped
|
|
31
|
+
@urls: Array[URI::Generic]
|
|
32
|
+
@table: Array[Array[String?]]
|
|
33
|
+
|
|
34
|
+
def initialize: (untyped csv_path) -> void
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
def urls: -> Array[URI::Generic]
|
|
38
|
+
def table: -> Array[Array[String?]]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class BlastEmails
|
|
42
|
+
@csv_path: untyped
|
|
43
|
+
@email_address: String?
|
|
44
|
+
@table: Array[Array[String?]]
|
|
45
|
+
@ui_language: String?
|
|
46
|
+
@learning_language: String?
|
|
47
|
+
@enabled: bool
|
|
48
|
+
@announcement: bool
|
|
49
|
+
@creation_datetime: untyped
|
|
50
|
+
@last_session: untyped
|
|
51
|
+
@trial_user: bool
|
|
52
|
+
@country: String?
|
|
53
|
+
@client: String?
|
|
54
|
+
@schools_role: Integer
|
|
55
|
+
|
|
56
|
+
def initialize: (untyped csv_path) -> void
|
|
57
|
+
def email_address: -> String?
|
|
58
|
+
def ui_language: -> String?
|
|
59
|
+
def learning_language: -> String?
|
|
60
|
+
def enabled: -> bool
|
|
61
|
+
def announcement: -> bool
|
|
62
|
+
def creation_datetime: -> untyped
|
|
63
|
+
def last_session: -> untyped
|
|
64
|
+
def trial_user: -> bool
|
|
65
|
+
def country: -> String?
|
|
66
|
+
def client: -> String?
|
|
67
|
+
def schools_role: -> Integer
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
def value_from_property: (String property_name) -> String?
|
|
71
|
+
def boolean_value_from_property: (String property_name) -> bool
|
|
72
|
+
def time_value_from_property: (String property_name) -> untyped
|
|
73
|
+
def integer_value_from_property: (String property_name) -> Integer
|
|
74
|
+
def table: -> Array[Array[String?]]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class FriendsFollow
|
|
78
|
+
@csv_path: untyped
|
|
79
|
+
@num_following: Integer
|
|
80
|
+
@table: Array[Array[String?]]
|
|
81
|
+
@num_followers: Integer
|
|
82
|
+
@num_blocking: Integer
|
|
83
|
+
@num_blockers: Integer
|
|
84
|
+
@timestamp_generated: Time
|
|
85
|
+
|
|
86
|
+
def initialize: (untyped csv_path) -> void
|
|
87
|
+
def num_following: -> Integer
|
|
88
|
+
def num_followers: -> Integer
|
|
89
|
+
def num_blocking: -> Integer
|
|
90
|
+
def num_blockers: -> Integer
|
|
91
|
+
def timestamp_generated: -> Time
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
def value_from_property: (String property_name) -> String?
|
|
95
|
+
def integer_value_from_property: (String property_name) -> Integer
|
|
96
|
+
def timestamp_value_from_property: (String property_name) -> Time
|
|
97
|
+
def table: -> Array[Array[String?]]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
class InventoryItem < Struct[untyped]
|
|
101
|
+
attr_accessor item_type(): String?
|
|
102
|
+
attr_accessor purchase_datetime(): untyped
|
|
103
|
+
attr_accessor active(): bool
|
|
104
|
+
attr_accessor price_in_virtual_currency(): Integer
|
|
105
|
+
attr_accessor wager_day(): Integer
|
|
106
|
+
attr_accessor payment_processor(): String?
|
|
107
|
+
attr_accessor product(): String?
|
|
108
|
+
attr_accessor expected_expiration(): untyped
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
class Inventory
|
|
112
|
+
extend Forwardable
|
|
113
|
+
@csv_path: untyped
|
|
114
|
+
@items: Array[InventoryItem]
|
|
115
|
+
@table: Array[Array[String?]]
|
|
116
|
+
|
|
117
|
+
def initialize: (untyped csv_path) -> void
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
def items: -> Array[InventoryItem]
|
|
121
|
+
def parse_datetime: (String? str) -> untyped
|
|
122
|
+
def parse_boolean: (String? str) -> bool
|
|
123
|
+
def table: -> Array[Array[String?]]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class Language < Struct[untyped]
|
|
127
|
+
attr_accessor from_language(): String?
|
|
128
|
+
attr_accessor points(): Integer
|
|
129
|
+
attr_accessor skill_learned(): Integer
|
|
130
|
+
attr_accessor total_lessons(): Integer
|
|
131
|
+
attr_accessor days_active(): Integer
|
|
132
|
+
attr_accessor last_active(): untyped
|
|
133
|
+
attr_accessor prior_proficiency(): Integer
|
|
134
|
+
attr_accessor subscribed(): untyped
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
class Languages
|
|
138
|
+
extend Forwardable
|
|
139
|
+
@csv_path: untyped
|
|
140
|
+
@languages: Hash[String?, Language]
|
|
141
|
+
|
|
142
|
+
def initialize: (untyped csv_path) -> void
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
def languages: -> Hash[String?, Language]
|
|
146
|
+
def parse_datetime: (String str) -> untyped
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
class LeaderboardsEntry < Struct[untyped]
|
|
150
|
+
attr_accessor timestamp(): untyped
|
|
151
|
+
attr_accessor tier(): Integer
|
|
152
|
+
attr_accessor score(): Float
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
class Leaderboards
|
|
156
|
+
extend Forwardable
|
|
157
|
+
@csv_path: untyped
|
|
158
|
+
@entries: Array[LeaderboardsEntry]
|
|
159
|
+
|
|
160
|
+
def initialize: (untyped csv_path) -> void
|
|
161
|
+
|
|
162
|
+
private
|
|
163
|
+
def entries: -> Array[LeaderboardsEntry]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
class NotifyData
|
|
167
|
+
@csv_path: untyped
|
|
168
|
+
@email: String?
|
|
169
|
+
@table: Array[Array[String?]]
|
|
170
|
+
@device_ids: untyped
|
|
171
|
+
|
|
172
|
+
def initialize: (untyped csv_path) -> void
|
|
173
|
+
def email: -> String?
|
|
174
|
+
def device_ids: -> untyped
|
|
175
|
+
|
|
176
|
+
private
|
|
177
|
+
def value_from_property: (String property_name) -> String?
|
|
178
|
+
def json_value_from_property: (String property_name) -> untyped
|
|
179
|
+
def table: -> Array[Array[String?]]
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
class Profile
|
|
183
|
+
@csv_path: untyped
|
|
184
|
+
@username: String?
|
|
185
|
+
@table: Array[Array[String?]]
|
|
186
|
+
@email: String?
|
|
187
|
+
@fullname: String?
|
|
188
|
+
@joined_at: untyped
|
|
189
|
+
@ui_language: String?
|
|
190
|
+
@learning_language: String?
|
|
191
|
+
@lingots: Integer
|
|
192
|
+
@daily_goal: Integer
|
|
193
|
+
@timezone: String?
|
|
194
|
+
@avatar_url: String?
|
|
195
|
+
|
|
196
|
+
def initialize: (untyped csv_path) -> void
|
|
197
|
+
def username: -> String?
|
|
198
|
+
def email: -> String?
|
|
199
|
+
def fullname: -> String?
|
|
200
|
+
def joined_at: -> untyped
|
|
201
|
+
def ui_language: -> String?
|
|
202
|
+
def learning_language: -> String?
|
|
203
|
+
def lingots: -> Integer
|
|
204
|
+
def daily_goal: -> Integer
|
|
205
|
+
def timezone: -> String?
|
|
206
|
+
def avatar_url: -> String?
|
|
207
|
+
|
|
208
|
+
private
|
|
209
|
+
def value_from_property: (String property_name) -> String?
|
|
210
|
+
def integer_value_from_property: (String property_name) -> Integer
|
|
211
|
+
def datetime_value_from_property: (String property_name) -> untyped
|
|
212
|
+
def table: -> Array[Array[String?]]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
class Stories
|
|
216
|
+
@csv_path: untyped
|
|
217
|
+
@user_id: String?
|
|
218
|
+
@table: Array[Array[String?]]
|
|
219
|
+
@date_of_first_visit_to_stories: untyped
|
|
220
|
+
|
|
221
|
+
def initialize: (untyped csv_path) -> void
|
|
222
|
+
def user_id: -> String?
|
|
223
|
+
def date_of_first_visit_to_stories: -> untyped
|
|
224
|
+
|
|
225
|
+
private
|
|
226
|
+
def value_from_property: (String property_name) -> String?
|
|
227
|
+
def datetime_value_from_property: (String property_name) -> untyped
|
|
228
|
+
def table: -> Array[Array[String?]]
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
class StoryCompletion < Struct[untyped]
|
|
232
|
+
attr_accessor user_id(): String?
|
|
233
|
+
attr_accessor story_id(): String?
|
|
234
|
+
attr_accessor score(): Integer
|
|
235
|
+
attr_accessor time(): untyped
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
class StoryCompletions
|
|
239
|
+
extend Forwardable
|
|
240
|
+
@csv_path: untyped
|
|
241
|
+
@completions: Array[StoryCompletion]
|
|
242
|
+
|
|
243
|
+
def initialize: (untyped csv_path) -> void
|
|
244
|
+
|
|
245
|
+
private
|
|
246
|
+
def completions: -> Array[StoryCompletion]
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
class TeacherPrivacySettings
|
|
250
|
+
@csv_path: untyped
|
|
251
|
+
@disable_clubs: bool
|
|
252
|
+
@table: Array[Array[String?]]
|
|
253
|
+
@disable_discussions: bool
|
|
254
|
+
@disable_events: bool
|
|
255
|
+
@disable_stream: bool
|
|
256
|
+
@disable_immersion: bool
|
|
257
|
+
@disable_mature_words: bool
|
|
258
|
+
|
|
259
|
+
def initialize: (untyped csv_path) -> void
|
|
260
|
+
def disable_clubs: -> bool
|
|
261
|
+
def disable_discussions: -> bool
|
|
262
|
+
def disable_events: -> bool
|
|
263
|
+
def disable_stream: -> bool
|
|
264
|
+
def disable_immersion: -> bool
|
|
265
|
+
def disable_mature_words: -> bool
|
|
266
|
+
|
|
267
|
+
private
|
|
268
|
+
def boolean_value_from_property: (String property_name) -> bool
|
|
269
|
+
def value_from_property: (String property_name) -> String?
|
|
270
|
+
def table: -> Array[Array[String?]]
|
|
271
|
+
end
|
|
272
|
+
end
|