spaceship 0.0.15 → 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 +4 -4
- data/lib/assets/languageMapping.json +224 -0
- data/lib/spaceship.rb +20 -63
- data/lib/spaceship/base.rb +71 -14
- data/lib/spaceship/client.rb +9 -274
- data/lib/spaceship/launcher.rb +1 -1
- data/lib/spaceship/portal/app.rb +125 -0
- data/lib/spaceship/portal/certificate.rb +273 -0
- data/lib/spaceship/portal/device.rb +102 -0
- data/lib/spaceship/portal/portal.rb +6 -0
- data/lib/spaceship/portal/portal_base.rb +13 -0
- data/lib/spaceship/portal/portal_client.rb +289 -0
- data/lib/spaceship/portal/provisioning_profile.rb +369 -0
- data/lib/spaceship/portal/spaceship.rb +94 -0
- data/lib/spaceship/{ui → portal/ui}/select_team.rb +0 -0
- data/lib/spaceship/tunes/app_screenshot.rb +28 -0
- data/lib/spaceship/tunes/app_status.rb +63 -0
- data/lib/spaceship/tunes/app_submission.rb +149 -0
- data/lib/spaceship/tunes/app_version.rb +337 -0
- data/lib/spaceship/tunes/application.rb +253 -0
- data/lib/spaceship/tunes/build.rb +128 -0
- data/lib/spaceship/tunes/build_train.rb +79 -0
- data/lib/spaceship/tunes/language_converter.rb +44 -0
- data/lib/spaceship/tunes/language_item.rb +54 -0
- data/lib/spaceship/tunes/processing_build.rb +30 -0
- data/lib/spaceship/tunes/spaceship.rb +26 -0
- data/lib/spaceship/tunes/tester.rb +177 -0
- data/lib/spaceship/tunes/tunes.rb +12 -0
- data/lib/spaceship/tunes/tunes_base.rb +15 -0
- data/lib/spaceship/tunes/tunes_client.rb +360 -0
- data/lib/spaceship/version.rb +1 -1
- metadata +27 -7
- data/lib/spaceship/app.rb +0 -125
- data/lib/spaceship/certificate.rb +0 -271
- data/lib/spaceship/device.rb +0 -100
- data/lib/spaceship/provisioning_profile.rb +0 -367
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Spaceship
|
2
|
+
module Tunes
|
3
|
+
# Represents a screenshot hosted on iTunes Connect
|
4
|
+
class AppScreenshot
|
5
|
+
|
6
|
+
attr_accessor :thumbnail_url
|
7
|
+
|
8
|
+
attr_accessor :sort_order
|
9
|
+
|
10
|
+
attr_accessor :original_file_name
|
11
|
+
|
12
|
+
attr_accessor :url
|
13
|
+
|
14
|
+
attr_accessor :device_type
|
15
|
+
|
16
|
+
attr_accessor :language
|
17
|
+
|
18
|
+
def initialize(hash)
|
19
|
+
self.thumbnail_url = hash[:thumbnail_url]
|
20
|
+
self.sort_order = hash[:sort_order]
|
21
|
+
self.original_file_name = hash[:original_file_name]
|
22
|
+
self.url = hash[:url]
|
23
|
+
self.device_type = hash[:device_type]
|
24
|
+
self.language = hash[:language]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Spaceship
|
2
|
+
module Tunes
|
3
|
+
# Defines the different states of the app
|
4
|
+
#
|
5
|
+
# As specified by Apple: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/ChangingAppStatus.html
|
6
|
+
module AppStatus
|
7
|
+
# You can edit this version, upload new binaries and more
|
8
|
+
PREPARE_FOR_SUBMISSION = "Prepare for Submission"
|
9
|
+
|
10
|
+
# App is currently live in the App Store
|
11
|
+
READY_FOR_SALE = "Ready for Sale"
|
12
|
+
|
13
|
+
# Waiting for Apple's Review
|
14
|
+
WAITING_FOR_REVIEW = "Waiting For Review"
|
15
|
+
|
16
|
+
# Currently in Review
|
17
|
+
IN_REVIEW = "In Review"
|
18
|
+
|
19
|
+
# App rejected for whatever reason
|
20
|
+
REJECTED = "Rejected"
|
21
|
+
|
22
|
+
# The developer took the app from the App Store
|
23
|
+
DEVELOPER_REMOVED_FROM_SALE = "Developer Removed From Sale"
|
24
|
+
|
25
|
+
# Developer rejected this version/binary
|
26
|
+
DEVELOPER_REJECTED = "Developer Rejected"
|
27
|
+
|
28
|
+
# You have to renew your Apple account to keep using iTunes Connect
|
29
|
+
PENDING_CONTRACT = "Pending Contract"
|
30
|
+
|
31
|
+
UPLOAD_RECEIVED = "Upload Received"
|
32
|
+
PENDING_DEVELOPER_RELEASE = "Pending Developer Release"
|
33
|
+
PROCESSING_FOR_APP_STORE = "Processing for App Store"
|
34
|
+
|
35
|
+
# Unused app states
|
36
|
+
# PENDING_APPLE_RELASE = "Pending Apple Release"
|
37
|
+
|
38
|
+
# WAITING_FOR_EXPORT_COMPLIANCE = "Waiting For Export Compliance"
|
39
|
+
# METADATA_REJECTED = "Metadata Rejected"
|
40
|
+
# REMOVED_FROM_SALE = "Removed From Sale"
|
41
|
+
# INVALID_BINARY = "Invalid Binary"
|
42
|
+
|
43
|
+
|
44
|
+
# Get the app status matching based on a string (given by iTunes Connect)
|
45
|
+
def self.get_from_string(text)
|
46
|
+
mapping = {
|
47
|
+
'readyForSale' => READY_FOR_SALE,
|
48
|
+
'prepareForUpload' => PREPARE_FOR_SUBMISSION,
|
49
|
+
'devRejected' => DEVELOPER_REJECTED,
|
50
|
+
'pendingContract' => PENDING_CONTRACT,
|
51
|
+
'developerRemovedFromSale' => DEVELOPER_REMOVED_FROM_SALE,
|
52
|
+
'waitingForReview' => WAITING_FOR_REVIEW
|
53
|
+
}
|
54
|
+
|
55
|
+
mapping.each do |k, v|
|
56
|
+
return v if k == text
|
57
|
+
end
|
58
|
+
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module Spaceship
|
2
|
+
module Tunes
|
3
|
+
# Represents a submission for review of an iTunes Connect Application
|
4
|
+
# This class handles the submission of all review information and documents
|
5
|
+
class AppSubmission < TunesBase
|
6
|
+
# @return (Spaceship::Tunes::Application) A reference to the application
|
7
|
+
# this submission is for
|
8
|
+
attr_accessor :application
|
9
|
+
|
10
|
+
# @return (AppVersion) The version to use for this submission
|
11
|
+
attr_accessor :version
|
12
|
+
|
13
|
+
# @return (String) The stage of this submission (start, complete)
|
14
|
+
attr_accessor :stage
|
15
|
+
|
16
|
+
# @return (Boolean) Submitted for Review
|
17
|
+
attr_accessor :submitted_for_review
|
18
|
+
|
19
|
+
# @return (Boolean) Ad ID Info - Limits ads tracking
|
20
|
+
attr_accessor :add_id_info_limits_tracking
|
21
|
+
|
22
|
+
# @return (Boolean) Ad ID Info - Serves ads
|
23
|
+
attr_accessor :add_id_info_serves_ads
|
24
|
+
|
25
|
+
# @return (Boolean) Ad ID Info - Tracks actions
|
26
|
+
attr_accessor :add_id_info_tracks_action
|
27
|
+
|
28
|
+
# @return (Boolean) Ad ID Info - Tracks installs
|
29
|
+
attr_accessor :add_id_info_tracks_install
|
30
|
+
|
31
|
+
# @return (Boolean) Ad ID Info - Uses idfa
|
32
|
+
attr_accessor :add_id_info_uses_idfa
|
33
|
+
|
34
|
+
# @return (Boolean) Content Rights - Contains third party content
|
35
|
+
attr_accessor :content_rights_contains_third_party_content
|
36
|
+
|
37
|
+
# @return (Boolean) Content Rights - Has rights of content
|
38
|
+
attr_accessor :content_rights_has_rights
|
39
|
+
|
40
|
+
# @return (Boolean) Export Compliance - Available on French Store
|
41
|
+
attr_accessor :export_compliance_available_on_french_store
|
42
|
+
|
43
|
+
# @return (@TODO) Export Compliance - CCAT File
|
44
|
+
attr_accessor :export_compliance_ccat_file
|
45
|
+
|
46
|
+
# @return (Boolean) Export Compliance - Contains proprietary cryptography
|
47
|
+
attr_accessor :export_compliance_contains_proprietary_cryptography
|
48
|
+
|
49
|
+
# @return (Boolean) Export Compliance - Contains third-party cryptography
|
50
|
+
attr_accessor :export_compliance_contains_third_party_cryptography
|
51
|
+
|
52
|
+
# @return (Boolean) Export Compliance - Is exempt
|
53
|
+
attr_accessor :export_compliance_is_exempt
|
54
|
+
|
55
|
+
# @return (Boolean) Export Compliance - Uses encryption
|
56
|
+
attr_accessor :export_compliance_uses_encryption
|
57
|
+
|
58
|
+
# @return (String) Export Compliance - App type
|
59
|
+
attr_accessor :export_compliance_app_type
|
60
|
+
|
61
|
+
# @return (Boolean) Export Compliance - Encryption Updated
|
62
|
+
attr_accessor :export_compliance_encryption_updated
|
63
|
+
|
64
|
+
# @return (Boolean) Export Compliance - Compliance Required
|
65
|
+
attr_accessor :export_compliance_compliance_required
|
66
|
+
|
67
|
+
# @return (String) Export Compliance - Platform
|
68
|
+
attr_accessor :export_compliance_platform
|
69
|
+
|
70
|
+
attr_mapping({
|
71
|
+
|
72
|
+
# Ad ID Info Section
|
73
|
+
'adIdInfo.limitsTracking.value' => :add_id_info_limits_tracking,
|
74
|
+
'adIdInfo.servesAds.value' => :add_id_info_serves_ads,
|
75
|
+
'adIdInfo.tracksAction.value' => :add_id_info_tracks_action,
|
76
|
+
'adIdInfo.tracksInstall.value' => :add_id_info_tracks_install,
|
77
|
+
'adIdInfo.usesIdfa.value' => :add_id_info_uses_idfa,
|
78
|
+
|
79
|
+
# Content Rights Section
|
80
|
+
'contentRights.containsThirdPartyContent.value' => :content_rights_contains_third_party_content,
|
81
|
+
'contentRights.hasRights.value' => :content_rights_has_rights,
|
82
|
+
|
83
|
+
# Export Compliance Section
|
84
|
+
'exportCompliance.availableOnFrenchStore.value' => :export_compliance_available_on_french_store,
|
85
|
+
'exportCompliance.ccatFile.value' => :export_compliance_ccat_file,
|
86
|
+
'exportCompliance.containsProprietaryCryptography.value' => :export_compliance_contains_proprietary_cryptography,
|
87
|
+
'exportCompliance.containsThirdPartyCryptography.value' => :export_compliance_contains_third_party_cryptography,
|
88
|
+
'exportCompliance.isExempt.value' => :export_compliance_is_exempt,
|
89
|
+
'exportCompliance.usesEncryption.value' => :export_compliance_uses_encryption,
|
90
|
+
'exportCompliance.appType' => :export_compliance_app_type,
|
91
|
+
'exportCompliance.encryptionUpdated' => :export_compliance_encryption_updated,
|
92
|
+
'exportCompliance.exportComplianceRequired' => :export_compliance_compliance_required,
|
93
|
+
'exportCompliance.platform' => :export_compliance_platform
|
94
|
+
})
|
95
|
+
|
96
|
+
class << self
|
97
|
+
# Create a new object based on a hash.
|
98
|
+
# This is used to create a new object based on the server response.
|
99
|
+
def factory(attrs)
|
100
|
+
orig = attrs.dup
|
101
|
+
|
102
|
+
# fill content rights section if iTC returns nil
|
103
|
+
if attrs["contentRights"].nil?
|
104
|
+
attrs.merge!("contentRights" => {
|
105
|
+
"containsThirdPartyContent" => {
|
106
|
+
"value" => nil
|
107
|
+
},
|
108
|
+
"hasRights" => {
|
109
|
+
"value" => nil
|
110
|
+
}
|
111
|
+
})
|
112
|
+
end
|
113
|
+
|
114
|
+
obj = self.new(attrs)
|
115
|
+
return obj
|
116
|
+
end
|
117
|
+
|
118
|
+
# @param application (Spaceship::Tunes::Application) The app this submission is for
|
119
|
+
# @param app_id (String) The unique Apple ID of this app
|
120
|
+
def create(application, app_id, version)
|
121
|
+
stage = "start"
|
122
|
+
attrs = client.send_app_submission(application.apple_id, version.raw_data, stage)
|
123
|
+
attrs.merge!(application: application)
|
124
|
+
attrs.merge!(version: version)
|
125
|
+
attrs.merge!(stage: stage)
|
126
|
+
|
127
|
+
return self.factory(attrs)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Save and complete the app submission
|
132
|
+
def complete!
|
133
|
+
@stage = "complete"
|
134
|
+
client.send_app_submission(application.apple_id, raw_data, @stage)
|
135
|
+
@submitted_for_review = true
|
136
|
+
end
|
137
|
+
|
138
|
+
# @return (String) An URL to this specific resource. You can enter this URL into your browser
|
139
|
+
def url
|
140
|
+
"https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/#{self.application.apple_id}/version/submit/#{self.stage}"
|
141
|
+
end
|
142
|
+
|
143
|
+
def setup
|
144
|
+
@submitted_for_review = false
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,337 @@
|
|
1
|
+
module Spaceship
|
2
|
+
module Tunes
|
3
|
+
# Represents an editable version of an iTunes Connect Application
|
4
|
+
# This can either be the live or the edit version retrieved via the app
|
5
|
+
class AppVersion < TunesBase
|
6
|
+
# @return (Spaceship::Tunes::Application) A reference to the application
|
7
|
+
# this version is for
|
8
|
+
attr_accessor :application
|
9
|
+
|
10
|
+
# @return (String) The version number of this version
|
11
|
+
attr_accessor :version
|
12
|
+
|
13
|
+
# @return (String) The copyright information of this app
|
14
|
+
attr_accessor :copyright
|
15
|
+
|
16
|
+
# @return (Spaceship::Tunes::AppStatus) What's the current status of this app
|
17
|
+
# e.g. Waiting for Review, Ready for Sale, ...
|
18
|
+
attr_reader :app_status
|
19
|
+
|
20
|
+
# @return (Bool) Is that the version that's currently available in the App Store?
|
21
|
+
attr_accessor :is_live
|
22
|
+
|
23
|
+
# Categories (e.g. MZGenre.Business)
|
24
|
+
attr_accessor :primary_category
|
25
|
+
|
26
|
+
attr_accessor :primary_first_sub_category
|
27
|
+
|
28
|
+
attr_accessor :primary_second_sub_category
|
29
|
+
|
30
|
+
attr_accessor :secondary_category
|
31
|
+
|
32
|
+
attr_accessor :secondary_first_sub_category
|
33
|
+
|
34
|
+
attr_accessor :secondary_second_sub_category
|
35
|
+
|
36
|
+
# @return (String) App Status (e.g. 'readyForSale'). You should use `app_status` instead
|
37
|
+
attr_accessor :raw_status
|
38
|
+
|
39
|
+
# @return (Bool)
|
40
|
+
attr_accessor :can_reject_version
|
41
|
+
|
42
|
+
# @return (Bool)
|
43
|
+
attr_accessor :can_prepare_for_upload
|
44
|
+
|
45
|
+
# @return (Bool)
|
46
|
+
attr_accessor :can_send_version_live
|
47
|
+
|
48
|
+
# @return (Bool) Should the app automatically be released once it's approved?
|
49
|
+
attr_accessor :release_on_approval
|
50
|
+
|
51
|
+
# @return (Bool)
|
52
|
+
attr_accessor :can_beta_test
|
53
|
+
|
54
|
+
# @return (Bool) Does the binary contain a watch binary?
|
55
|
+
attr_accessor :supports_apple_watch
|
56
|
+
|
57
|
+
# @return (String) URL to the full resolution 1024x1024 app icon
|
58
|
+
attr_accessor :app_icon_url
|
59
|
+
|
60
|
+
# @return (String) Name of the original file
|
61
|
+
attr_accessor :app_icon_original_name
|
62
|
+
|
63
|
+
# @return (String) URL to the full resolution 1024x1024 app icon
|
64
|
+
attr_accessor :watch_app_icon_url
|
65
|
+
|
66
|
+
# @return (String) Name of the original file
|
67
|
+
attr_accessor :watch_app_icon_original_name
|
68
|
+
|
69
|
+
# @return (Integer) a unqiue ID for this version generated by iTunes Connect
|
70
|
+
attr_accessor :version_id
|
71
|
+
|
72
|
+
# @return TODO
|
73
|
+
attr_accessor :company_information
|
74
|
+
|
75
|
+
####
|
76
|
+
# App Review Information
|
77
|
+
####
|
78
|
+
# @return (String) App Review Information First Name
|
79
|
+
attr_accessor :review_first_name
|
80
|
+
|
81
|
+
# @return (String) App Review Information Last Name
|
82
|
+
attr_accessor :review_last_name
|
83
|
+
|
84
|
+
# @return (String) App Review Information Phone Number
|
85
|
+
attr_accessor :review_phone_number
|
86
|
+
|
87
|
+
# @return (String) App Review Information Email Address
|
88
|
+
attr_accessor :review_email
|
89
|
+
|
90
|
+
# @return (String) App Review Information Demo Account User Name
|
91
|
+
attr_accessor :review_demo_user
|
92
|
+
|
93
|
+
# @return (String) App Review Information Demo Account Password
|
94
|
+
attr_accessor :review_demo_password
|
95
|
+
|
96
|
+
# @return (String) App Review Information Notes
|
97
|
+
attr_accessor :review_notes
|
98
|
+
|
99
|
+
####
|
100
|
+
# Localized values:
|
101
|
+
####
|
102
|
+
|
103
|
+
# @return (Array) Raw access the all available languages. You shouldn't use it probbaly
|
104
|
+
attr_accessor :languages
|
105
|
+
|
106
|
+
# @return (Hash) A hash representing the app name in all languages
|
107
|
+
attr_reader :name
|
108
|
+
|
109
|
+
# @return (Hash) A hash representing the keywords in all languages
|
110
|
+
attr_reader :keywords
|
111
|
+
|
112
|
+
# @return (Hash) A hash representing the description in all languages
|
113
|
+
attr_reader :description
|
114
|
+
|
115
|
+
# @return (Hash) The changelog
|
116
|
+
attr_reader :release_notes
|
117
|
+
|
118
|
+
# @return (Hash) A hash representing the keywords in all languages
|
119
|
+
attr_reader :privacy_url
|
120
|
+
|
121
|
+
# @return (Hash) A hash representing the keywords in all languages
|
122
|
+
attr_reader :support_url
|
123
|
+
|
124
|
+
# @return (Hash) A hash representing the keywords in all languages
|
125
|
+
attr_reader :marketing_url
|
126
|
+
|
127
|
+
# @return (Hash) Represents the screenshots of this app version (read-only)
|
128
|
+
attr_reader :screenshots
|
129
|
+
|
130
|
+
|
131
|
+
attr_mapping({
|
132
|
+
'canBetaTest' => :can_beta_test,
|
133
|
+
'canPrepareForUpload' => :can_prepare_for_upload,
|
134
|
+
'canRejectVersion' => :can_reject_version,
|
135
|
+
'canSendVersionLive' => :can_send_version_live,
|
136
|
+
'copyright.value' => :copyright,
|
137
|
+
'details.value' => :languages,
|
138
|
+
'largeAppIcon.value.originalFileName' => :app_icon_original_name,
|
139
|
+
'largeAppIcon.value.url' => :app_icon_url,
|
140
|
+
'primaryCategory.value' => :primary_category,
|
141
|
+
'primaryFirstSubCategory.value' => :primary_first_sub_category,
|
142
|
+
'primarySecondSubCategory.value' => :primary_second_sub_category,
|
143
|
+
'releaseOnApproval.value' => :release_on_approval,
|
144
|
+
'secondaryCategory.value' => :secondary_category,
|
145
|
+
'secondaryFirstSubCategory.value' => :secondary_first_sub_category,
|
146
|
+
'secondarySecondSubCategory.value' => :secondary_second_sub_category,
|
147
|
+
'status' => :raw_status,
|
148
|
+
'supportsAppleWatch' => :supports_apple_watch,
|
149
|
+
'versionId' => :version_id,
|
150
|
+
'version.value' => :version,
|
151
|
+
'watchAppIcon.value.originalFileName' => :watch_app_icon_original_name,
|
152
|
+
'watchAppIcon.value.url' => :watch_app_icon_url,
|
153
|
+
|
154
|
+
# App Review Information
|
155
|
+
'appReviewInfo.firstName.value' => :review_first_name,
|
156
|
+
'appReviewInfo.lastName.value' => :review_last_name,
|
157
|
+
'appReviewInfo.phoneNumber.value' => :review_phone_number,
|
158
|
+
'appReviewInfo.emailAddress.value' => :review_email,
|
159
|
+
'appReviewInfo.reviewNotes.value' => :review_notes,
|
160
|
+
'appReviewInfo.userName.value' => :review_demo_user,
|
161
|
+
'appReviewInfo.password.value' => :review_demo_password
|
162
|
+
})
|
163
|
+
|
164
|
+
class << self
|
165
|
+
# Create a new object based on a hash.
|
166
|
+
# This is used to create a new object based on the server response.
|
167
|
+
def factory(attrs)
|
168
|
+
orig = attrs.dup
|
169
|
+
obj = self.new(attrs)
|
170
|
+
obj.unfold_languages
|
171
|
+
|
172
|
+
return obj
|
173
|
+
end
|
174
|
+
|
175
|
+
# @param application (Spaceship::Tunes::Application) The app this version is for
|
176
|
+
# @param app_id (String) The unique Apple ID of this app
|
177
|
+
# @param is_live (Boolean) Is that the version that's live in the App Store?
|
178
|
+
def find(application, app_id, is_live = false)
|
179
|
+
attrs = client.app_version(app_id, is_live)
|
180
|
+
attrs.merge!(application: application)
|
181
|
+
attrs.merge!(is_live: is_live)
|
182
|
+
|
183
|
+
return self.factory(attrs)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# @return (Bool) Is that version currently available in the App Store?
|
188
|
+
def is_live?
|
189
|
+
is_live
|
190
|
+
end
|
191
|
+
|
192
|
+
# Call this method to make sure the given languages are available for this app
|
193
|
+
# You should call this method before accessing the name, description and other localized values
|
194
|
+
# This will create the new language if it's not available yet and do nothing if everything's there
|
195
|
+
# def create_languages!(languages)
|
196
|
+
# raise "Please pass an array" unless languages.kind_of?Array
|
197
|
+
|
198
|
+
# copy_from = self.languages.first
|
199
|
+
# languages.each do |language|
|
200
|
+
# # First, see if it's already available
|
201
|
+
# found = self.languages.find do |local|
|
202
|
+
# local['language'] == language
|
203
|
+
# end
|
204
|
+
|
205
|
+
# unless found
|
206
|
+
# new_language = copy_from.dup
|
207
|
+
# new_language['language'] = language
|
208
|
+
# [:description, :releaseNotes, :keywords].each do |key|
|
209
|
+
# new_language[key.to_s]['value'] = nil
|
210
|
+
# end
|
211
|
+
|
212
|
+
# self.languages << new_language
|
213
|
+
# unfold_languages
|
214
|
+
|
215
|
+
# # Now we need to set a useless `pageLanguageValue` value because iTC says so, after adding a new version
|
216
|
+
# self.languages.each do |current|
|
217
|
+
# current['pageLanguageValue'] = current['language']
|
218
|
+
# end
|
219
|
+
# end
|
220
|
+
# end
|
221
|
+
|
222
|
+
# languages
|
223
|
+
# end
|
224
|
+
|
225
|
+
# Push all changes that were made back to iTunes Connect
|
226
|
+
def save!
|
227
|
+
client.update_app_version!(application.apple_id, is_live?, raw_data)
|
228
|
+
end
|
229
|
+
|
230
|
+
# @return (String) An URL to this specific resource. You can enter this URL into your browser
|
231
|
+
def url
|
232
|
+
"https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/#{self.application.apple_id}/" + (self.is_live? ? "cur" : "")
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
# Private methods
|
237
|
+
def setup
|
238
|
+
# Properly parse the AppStatus
|
239
|
+
status = raw_data['status']
|
240
|
+
@app_status = Tunes::AppStatus.get_from_string(status)
|
241
|
+
|
242
|
+
# Setup the screenshots
|
243
|
+
@screenshots = {}
|
244
|
+
raw_data['details']['value'].each do |row|
|
245
|
+
# Now that's one language right here
|
246
|
+
@screenshots[row['language']] = setup_screenshots(row)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
# Prefill name, keywords, etc...
|
252
|
+
def unfold_languages
|
253
|
+
{
|
254
|
+
name: :name,
|
255
|
+
keywords: :keywords,
|
256
|
+
description: :description,
|
257
|
+
privacyURL: :privacy_url,
|
258
|
+
supportURL: :support_url,
|
259
|
+
marketingURL: :marketing_url,
|
260
|
+
releaseNotes: :release_notes
|
261
|
+
}.each do |json, attribute|
|
262
|
+
instance_variable_set("@#{attribute}".to_sym, LanguageItem.new(json, languages))
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# These methods takes care of properly parsing values that
|
267
|
+
# are not returned in the right format, e.g. boolean as string
|
268
|
+
def release_on_approval
|
269
|
+
super == 'true'
|
270
|
+
end
|
271
|
+
|
272
|
+
def supports_apple_watch
|
273
|
+
(super != nil)
|
274
|
+
end
|
275
|
+
|
276
|
+
def primary_category=(value)
|
277
|
+
value = "MZGenre.#{value}" unless value.include?"MZGenre"
|
278
|
+
super(value)
|
279
|
+
end
|
280
|
+
|
281
|
+
def primary_category=(value)
|
282
|
+
value = "MZGenre.#{value}" unless value.include?"MZGenre"
|
283
|
+
super(value)
|
284
|
+
end
|
285
|
+
|
286
|
+
def primary_first_sub_cate=(value)gory
|
287
|
+
value = "MZGenre.#{value}" unless value.include?"MZGenre"
|
288
|
+
super(value)
|
289
|
+
end
|
290
|
+
|
291
|
+
def primary_second_sub_cat=(value)egory
|
292
|
+
value = "MZGenre.#{value}" unless value.include?"MZGenre"
|
293
|
+
super(value)
|
294
|
+
end
|
295
|
+
|
296
|
+
def secondary_category=(value)
|
297
|
+
value = "MZGenre.#{value}" unless value.include?"MZGenre"
|
298
|
+
super(value)
|
299
|
+
end
|
300
|
+
|
301
|
+
def secondary_first_sub_ca=(value)tegory
|
302
|
+
value = "MZGenre.#{value}" unless value.include?"MZGenre"
|
303
|
+
super(value)
|
304
|
+
end
|
305
|
+
|
306
|
+
def secondary_second_sub_c=(value)ategory
|
307
|
+
value = "MZGenre.#{value}" unless value.include?"MZGenre"
|
308
|
+
super(value)
|
309
|
+
end
|
310
|
+
|
311
|
+
private
|
312
|
+
# generates the nested data structure to represent screenshots
|
313
|
+
def setup_screenshots(row)
|
314
|
+
screenshots = row.fetch('screenshots', {}).fetch('value', nil)
|
315
|
+
return [] unless screenshots
|
316
|
+
|
317
|
+
result = []
|
318
|
+
|
319
|
+
screenshots.each do |device_type, value|
|
320
|
+
value['value'].each do |screenshot|
|
321
|
+
screenshot = screenshot['value']
|
322
|
+
result << Tunes::AppScreenshot.new({
|
323
|
+
url: screenshot['url'],
|
324
|
+
thumbnail_url: screenshot['thumbNailUrl'],
|
325
|
+
sort_order: screenshot['sortOrder'],
|
326
|
+
original_file_name: screenshot['originalFileName'],
|
327
|
+
device_type: device_type,
|
328
|
+
language: row['language']
|
329
|
+
})
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
return result
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|