spaceship 0.0.15 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|