applebot 0.0.1
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/Gemfile +3 -0
- data/Gemfile.lock +38 -0
- data/LICENSE +19 -0
- data/README.md +153 -0
- data/Rakefile +13 -0
- data/applebot.gemspec +27 -0
- data/bin/applebot +73 -0
- data/create_app_id_manifest.js +6 -0
- data/create_manifest.js +24 -0
- data/lib/applebot/command_proxy.rb +44 -0
- data/lib/applebot/commands.rb +74 -0
- data/lib/applebot/error.rb +97 -0
- data/lib/applebot/mkmf.rb +25 -0
- data/lib/applebot/shell.rb +79 -0
- data/lib/applebot/version.rb +5 -0
- data/lib/applebot.rb +109 -0
- data/phantom/_commands.json +318 -0
- data/phantom/applebot.js +656 -0
- data/phantom/create_app.js +355 -0
- data/phantom/create_app_id.js +80 -0
- data/phantom/create_profile.js +134 -0
- data/phantom/delete_app_id.js +57 -0
- data/phantom/download_profile.js +36 -0
- data/phantom/list_app_id.js +66 -0
- data/phantom/list_profile.js +23 -0
- data/phantom/reject_binary_app.js +73 -0
- data/phantom/remove_from_sale_app.js +50 -0
- data/phantom/update_app.js +309 -0
- data/update_app_manifest.js +9 -0
- metadata +143 -0
@@ -0,0 +1,355 @@
|
|
1
|
+
var require = patchRequire(require);
|
2
|
+
|
3
|
+
var fs = require('fs');
|
4
|
+
var AppleBot = require('applebot').AppleBot;
|
5
|
+
var CommandHandler = require('applebot').CommandHandler;
|
6
|
+
|
7
|
+
var commandHandler = new CommandHandler("create_app.js");
|
8
|
+
|
9
|
+
|
10
|
+
var userOptions = commandHandler.parseArgs();
|
11
|
+
var applebot = new AppleBot(commandHandler.getAuthFromArgs());
|
12
|
+
|
13
|
+
var LOAD_URL = "https://itunesconnect.apple.com";
|
14
|
+
|
15
|
+
applebot.openPage(LOAD_URL, function(page){
|
16
|
+
var findFieldName = applebot.shortcuts.findFieldName;
|
17
|
+
|
18
|
+
applebot.action("Click the Add New App button", function() {
|
19
|
+
page.click('.upload-app-button a');
|
20
|
+
});
|
21
|
+
|
22
|
+
applebot.action("Fill the App Information page", function() {
|
23
|
+
var fillOptions = {
|
24
|
+
'#appNameUpdateContainerId input': userOptions.title,
|
25
|
+
};
|
26
|
+
|
27
|
+
var skuFieldName = findFieldName(page, "SKU Number", '.middle > div');
|
28
|
+
fillOptions['input[name="' + skuFieldName + '"]'] = userOptions.sku;
|
29
|
+
|
30
|
+
var bundleIdsToFormValue = applebot.shortcuts.filterBundleIdsFromItunesConnect(page);
|
31
|
+
var bundleIdValue = bundleIdsToFormValue[userOptions.id];
|
32
|
+
if (!bundleIdValue) {
|
33
|
+
page.die("Error: could not find App ID in options");
|
34
|
+
}
|
35
|
+
fillOptions['.bundleIdentifierBox select'] = bundleIdValue;
|
36
|
+
|
37
|
+
|
38
|
+
page.fillSelectors('#mainForm', fillOptions, false);
|
39
|
+
page.click('.continueActionButton');
|
40
|
+
});
|
41
|
+
|
42
|
+
applebot.action('Fill the availability date information', function() {
|
43
|
+
var fillOptions = {};
|
44
|
+
var userDate = userOptions.availability_date;
|
45
|
+
if (userDate) {
|
46
|
+
var userDateParts = userDate.split("/");
|
47
|
+
if (userDateParts.length !== 3) {
|
48
|
+
page.exit("Error: Incorrect date format, should be MM/DD/YYYY");
|
49
|
+
}
|
50
|
+
var userMonthToValue = function(userMonth) {
|
51
|
+
return "" + parseInt(userMonth) - 1;
|
52
|
+
};
|
53
|
+
var userDayToValue = function(userDay) {
|
54
|
+
return "" + parseInt(userDay) - 1;
|
55
|
+
};
|
56
|
+
var userYearToValue = function(userYear) {
|
57
|
+
if (userYear == new Date().getFullYear()) {
|
58
|
+
return "0";
|
59
|
+
}
|
60
|
+
else {
|
61
|
+
return "1";
|
62
|
+
}
|
63
|
+
};
|
64
|
+
fillOptions['.date-select-month select'] = userMonthToValue(userDateParts[0]);
|
65
|
+
fillOptions['.date-select-day select'] = userDayToValue(userDateParts[1]);
|
66
|
+
fillOptions['.date-select-year select'] = userYearToValue(userDateParts[2]);
|
67
|
+
}
|
68
|
+
|
69
|
+
var userTierToValue = function(userTier) {
|
70
|
+
if (userTier === void(0) || userTier === 'free') {
|
71
|
+
return "0";
|
72
|
+
}
|
73
|
+
// i.e. Tier 1 == return 1
|
74
|
+
return userTier;
|
75
|
+
}
|
76
|
+
fillOptions["#pricingPopup"] = userTierToValue(userOptions.price_tier);
|
77
|
+
|
78
|
+
page.fillSelectors('#mainForm', fillOptions, false);
|
79
|
+
page.click('.continueActionButton');
|
80
|
+
});
|
81
|
+
|
82
|
+
applebot.action('Fill the version information page', function() {
|
83
|
+
var fillOptions = {};
|
84
|
+
|
85
|
+
///////////////////////////////////////
|
86
|
+
// Version Info
|
87
|
+
var versionInfoSelector = '.app-version > div';
|
88
|
+
var versionFieldName = findFieldName(page, "Version Number", versionInfoSelector);
|
89
|
+
fillOptions['input[name="' + versionFieldName + '"]'] = userOptions.app_version;
|
90
|
+
|
91
|
+
var copyrightFieldName = findFieldName(page, "Copyright", versionInfoSelector);
|
92
|
+
fillOptions['input[name="' + copyrightFieldName + '"]'] = userOptions.copyright;
|
93
|
+
|
94
|
+
///////////////////////////////////////
|
95
|
+
// Categories
|
96
|
+
var categories = ["Book", "Business", "Catalogs",
|
97
|
+
"Education", "Entertainment", "Finance",
|
98
|
+
"Food & Drink", "Games", "Health & Fitness",
|
99
|
+
"Lifestyle", "Medical", "Music", "Navigation",
|
100
|
+
"News", "Photo & Video", "Productivity",
|
101
|
+
"Reference", "Social Networking", "Sports",
|
102
|
+
"Travel", "Utilities", "Weather"
|
103
|
+
].map(function(cat) {
|
104
|
+
return cat.toLowerCase().replace(/\s/g, "_").replace("&", "and");
|
105
|
+
});
|
106
|
+
// TODO: games fucks up
|
107
|
+
var userCategoryToValue = function(userPrimary) {
|
108
|
+
return "" + categories.indexOf(userPrimary);
|
109
|
+
};
|
110
|
+
fillOptions["#version-primary-popup"] = userCategoryToValue(userOptions.primary_category);
|
111
|
+
fillOptions["#version-secondary-popup"] = userCategoryToValue(userOptions.secondary_category);
|
112
|
+
|
113
|
+
|
114
|
+
///////////////////////////////////////
|
115
|
+
// Content Ratings
|
116
|
+
var allDescriptions = page.evaluate(function() {
|
117
|
+
var descriptions = [];
|
118
|
+
var binaryDescriptions = []
|
119
|
+
var els = document.querySelectorAll('.mapping:first-child');
|
120
|
+
for (var i = 0; i < els.length; i++) {
|
121
|
+
var el = els[i];
|
122
|
+
var parent = el.parentElement;
|
123
|
+
if (parent.className !== "ratings-row") {
|
124
|
+
binaryDescriptions.push(el.innerHTML.trim());
|
125
|
+
}
|
126
|
+
else {
|
127
|
+
descriptions.push(el.innerHTML.trim());
|
128
|
+
}
|
129
|
+
}
|
130
|
+
return {normal: descriptions, binary: binaryDescriptions};
|
131
|
+
});
|
132
|
+
var contentDescriptions = allDescriptions.normal;
|
133
|
+
var binaryContentDescriptions = allDescriptions.binary;
|
134
|
+
|
135
|
+
var numContentRatings = contentDescriptions.length;
|
136
|
+
var contentDescriptionsToOptions = {};
|
137
|
+
for (var i = 0; i < contentDescriptions.length; i++) {
|
138
|
+
var description = contentDescriptions[i];
|
139
|
+
var key = description.toLowerCase().replace(/\s/g, "_").replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "")
|
140
|
+
contentDescriptionsToOptions[description] = key;
|
141
|
+
}
|
142
|
+
|
143
|
+
var iteratedValues = 0;
|
144
|
+
for (var i = 1; i <= numContentRatings; i++) {
|
145
|
+
var optionKey = contentDescriptionsToOptions[contentDescriptions[i - 1]];
|
146
|
+
var noneValue = "(MZPurpleContentDescriptorLevelRating#" + (i + 20) + ")";
|
147
|
+
var infrequentMildValue = "(MZPurpleContentDescriptorLevelRating#" + (iteratedValues + i) + ")";
|
148
|
+
var frequentIntenseValue = "(MZPurpleContentDescriptorLevelRating#" + (iteratedValues + (i + 1)) + ")";
|
149
|
+
var ratingValue = {
|
150
|
+
'none': noneValue,
|
151
|
+
'infrequent' : infrequentMildValue,
|
152
|
+
'frequent': frequentIntenseValue
|
153
|
+
};
|
154
|
+
|
155
|
+
var fillValue = undefined;
|
156
|
+
if (userOptions[optionKey]) {
|
157
|
+
var userRating = userOptions[optionKey];
|
158
|
+
fillValue = ratingValue[userRating];
|
159
|
+
}
|
160
|
+
if (!fillValue) {
|
161
|
+
fillValue = ratingValue['none'];
|
162
|
+
}
|
163
|
+
var fillKey = 'input[name="' + i + '"]';
|
164
|
+
fillOptions[fillKey] = fillValue;
|
165
|
+
iteratedValues += 1;
|
166
|
+
}
|
167
|
+
|
168
|
+
// Binary Content Restrictions
|
169
|
+
var numBinaryContentRatings = binaryContentDescriptions.length;
|
170
|
+
var binaryContentDescriptionsToOptions = {};
|
171
|
+
for (var i = 0; i < binaryContentDescriptions.length; i++) {
|
172
|
+
var description = binaryContentDescriptions[i];
|
173
|
+
var key = description.toLowerCase().replace(/\s/g, "_").replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "")
|
174
|
+
binaryContentDescriptionsToOptions[description] = key;
|
175
|
+
}
|
176
|
+
iteratedValues = 0;
|
177
|
+
for (var i = 1; i <= numBinaryContentRatings; i++) {
|
178
|
+
var optionKey = binaryContentDescriptionsToOptions[binaryContentDescriptions[i - 1]];
|
179
|
+
var noValue = "(MZPurpleContentDescriptorLevelRating#" + (i + iteratedValues + (numContentRatings * 3)) + ")";
|
180
|
+
var yesValue = "(MZPurpleContentDescriptorLevelRating#" + (iteratedValues + i + 1 + (numContentRatings * 3)) + ")";
|
181
|
+
var ratingValue = {
|
182
|
+
'no': noValue,
|
183
|
+
'yes' : yesValue
|
184
|
+
};
|
185
|
+
|
186
|
+
var fillValue = undefined;
|
187
|
+
if (userOptions[optionKey]) {
|
188
|
+
var userRating = userOptions[optionKey];
|
189
|
+
fillValue = ratingValue[userRating];
|
190
|
+
}
|
191
|
+
if (!fillValue) {
|
192
|
+
fillValue = ratingValue['no'];
|
193
|
+
}
|
194
|
+
var fillKey = 'input[name="' + (i + numContentRatings) + '"]';
|
195
|
+
fillOptions[fillKey] = fillValue;
|
196
|
+
iteratedValues += 1;
|
197
|
+
}
|
198
|
+
|
199
|
+
|
200
|
+
///////////////////////////////////////
|
201
|
+
// Metadata
|
202
|
+
fillOptions["#descriptionUpdateContainerId textarea"] = userOptions.description;
|
203
|
+
|
204
|
+
var metadataSelector = '.formfield-wrapper:nth-child(4) .app-info-container.app-landing.app-version > div';
|
205
|
+
var keywordsField = findFieldName(page, "Keywords", metadataSelector);
|
206
|
+
fillOptions['input[name="' + keywordsField + '"]'] = userOptions.keywords;
|
207
|
+
var supportUrlField = findFieldName(page, "Support URL", metadataSelector);
|
208
|
+
fillOptions['input[name="' + supportUrlField + '"]'] = userOptions.support_url;
|
209
|
+
if(userOptions.marketing_url) {
|
210
|
+
var marketingUrlField = findFieldName(page, "Marketing URL (Optional)", metadataSelector);
|
211
|
+
fillOptions['input[name="' + marketingUrlField + '"]'] = userOptions.marketing_url;
|
212
|
+
}
|
213
|
+
|
214
|
+
///////////////////////////////////////
|
215
|
+
// Contact Info
|
216
|
+
var contactInfoSelector = '#appReviewInitBox .field-section > div';
|
217
|
+
var firstNameField = findFieldName(page, "First Name", contactInfoSelector);
|
218
|
+
fillOptions['input[name="' + firstNameField + '"]'] = userOptions.first_name;
|
219
|
+
var lastNameField = findFieldName(page, "Last Name", contactInfoSelector);
|
220
|
+
fillOptions['input[name="' + lastNameField + '"]'] = userOptions.last_name;
|
221
|
+
var emailField = findFieldName(page, "Email Address", contactInfoSelector);
|
222
|
+
fillOptions['input[name="' + emailField + '"]'] = userOptions.email;
|
223
|
+
var phoneField = findFieldName(page, "Phone Number", contactInfoSelector);
|
224
|
+
fillOptions['input[name="' + phoneField + '"]'] = userOptions.phone;
|
225
|
+
|
226
|
+
if (userOptions.notes) {
|
227
|
+
fillOptions['#reviewnotes textarea'] = userOptions.notes;
|
228
|
+
}
|
229
|
+
|
230
|
+
page.fillSelectors('#versionInitForm', fillOptions, false);
|
231
|
+
});
|
232
|
+
|
233
|
+
applebot.action("Upload app icon", function() {
|
234
|
+
page.fillSelectors('form[name="FileUploadForm_largeAppIcon"]', {
|
235
|
+
'#fileInput_largeAppIcon': userOptions.large_icon
|
236
|
+
}, false);
|
237
|
+
});
|
238
|
+
|
239
|
+
applebot.action("Upload next 3.5in screenshot", function() {
|
240
|
+
var screenshotPath = applebot.shortcuts.popScreenshotPaths(userOptions, 'screenshots_35');
|
241
|
+
page.fillSelectors('form[name="FileUploadForm_35InchRetinaDisplayScreenshots"]', {
|
242
|
+
'#fileInput_35InchRetinaDisplayScreenshots': screenshotPath
|
243
|
+
}, false);
|
244
|
+
});
|
245
|
+
|
246
|
+
applebot.action("Upload next 4in screenshot", function() {
|
247
|
+
var screenshotPath = applebot.shortcuts.popScreenshotPaths(userOptions, 'screenshots_4');
|
248
|
+
page.fillSelectors('form[name="FileUploadForm_iPhone5"]', {
|
249
|
+
'#fileInput_iPhone5': screenshotPath
|
250
|
+
}, false);
|
251
|
+
});
|
252
|
+
|
253
|
+
applebot.action("Click Save button", function() {
|
254
|
+
page.click('.saveChangesActionButton');
|
255
|
+
});
|
256
|
+
|
257
|
+
applebot.action("Click Ready To Upload Binary button", function() {
|
258
|
+
page.click('.customActionButton');
|
259
|
+
});
|
260
|
+
|
261
|
+
applebot.action("Click the current version App Icon", function() {
|
262
|
+
page.click('.app-icon a');
|
263
|
+
});
|
264
|
+
|
265
|
+
applebot.action('Fill export compliance page', function() {
|
266
|
+
applebot.shortcuts.safeFill(page, '#mainForm', {
|
267
|
+
'firstQuestionRadio': "false", // Is your app designed to use cryptography
|
268
|
+
'ipContentsQuestionRadio': 'false',
|
269
|
+
'booleanRadioButton': 'false',
|
270
|
+
'hasLegalIssues': 'false'
|
271
|
+
}, false);
|
272
|
+
page.click('.saveChangesActionButton');
|
273
|
+
});
|
274
|
+
|
275
|
+
applebot.action("Click continue button", function() {
|
276
|
+
page.click(".continueActionButton");
|
277
|
+
});
|
278
|
+
|
279
|
+
|
280
|
+
///////////
|
281
|
+
// Steps
|
282
|
+
|
283
|
+
applebot.step("Wait for Manage Your Apps", 'waitForText', 'Recent Activity', function() {
|
284
|
+
applebot.action("Click the Add New App button");
|
285
|
+
});
|
286
|
+
|
287
|
+
applebot.step("Wait for the New App Information page", 'waitForSelector', '#mainForm', function() {
|
288
|
+
applebot.action("Fill the App Information page");
|
289
|
+
});
|
290
|
+
|
291
|
+
applebot.step("Wait for the Availability page", 'waitForText', 'Select the availability date and price tier for your app.', function() {
|
292
|
+
applebot.action("Fill the availability date information");
|
293
|
+
});
|
294
|
+
|
295
|
+
applebot.step("Wait for the Version Info page", 'waitForSelector', '#versionInitForm', function() {
|
296
|
+
applebot.action("Fill the version information page");
|
297
|
+
applebot.action("Upload app icon");
|
298
|
+
});
|
299
|
+
|
300
|
+
applebot.step("Wait for the app icon to upload", 'waitForSelector', '.LargeApplicationIcon', function() {
|
301
|
+
applebot.action("Upload next 3.5in screenshot");
|
302
|
+
});
|
303
|
+
|
304
|
+
var screenshotStepOptions = [{
|
305
|
+
key_path: 'screenshots_35',
|
306
|
+
selector: 'div.iPhoneScreenshot',
|
307
|
+
description: "3.5in",
|
308
|
+
next_step: "Upload next 4in screenshot",
|
309
|
+
while_step: "Upload next 3.5in screenshot"
|
310
|
+
}, {
|
311
|
+
key_path: 'screenshots_4',
|
312
|
+
selector: 'div.SortedN41ScreenShot',
|
313
|
+
description: "4in",
|
314
|
+
next_step: "Click Save button",
|
315
|
+
while_step: "Upload next 4in screenshot"
|
316
|
+
}];
|
317
|
+
|
318
|
+
for (var k = 0; k < screenshotStepOptions.length; k++) {
|
319
|
+
var screenshotStepOption = screenshotStepOptions[k];
|
320
|
+
applebot.shortcuts.addStepsForScreenshotGroup(applebot, page, userOptions, screenshotStepOption);
|
321
|
+
}
|
322
|
+
|
323
|
+
applebot.step("Wait for the App Summary page", 'waitForSelector', '.version-container', function() {
|
324
|
+
applebot.action("Click the current version App Icon");
|
325
|
+
}, {
|
326
|
+
timeout: 20 * 1000
|
327
|
+
});
|
328
|
+
|
329
|
+
applebot.step("Wait for App Version Summary page", 'waitForSelector', '.customActionButton', function() {
|
330
|
+
applebot.action("Click Ready To Upload Binary button");
|
331
|
+
}, {
|
332
|
+
timeout: 10 * 1000
|
333
|
+
});
|
334
|
+
|
335
|
+
applebot.step("Wait for the Export Compliance page", 'waitForText', 'Export Compliance', function() {
|
336
|
+
applebot.action('Fill export compliance page');
|
337
|
+
}, {
|
338
|
+
timeout: 10 * 1000
|
339
|
+
});
|
340
|
+
|
341
|
+
applebot.step("Wait for the Ready To Upload confirmation", 'waitForText', 'You are now ready to upload your binary', function() {
|
342
|
+
applebot.action("Click continue button");
|
343
|
+
}, {
|
344
|
+
timeout: 10 * 1000
|
345
|
+
});
|
346
|
+
|
347
|
+
applebot.step("Wait for Version Information confirmation", 'waitForText','Waiting For Upload', function() {
|
348
|
+
page.echo("Success");
|
349
|
+
}, {
|
350
|
+
timeout: 10 * 1000
|
351
|
+
});
|
352
|
+
|
353
|
+
|
354
|
+
applebot.shortcuts.openManageApps(page);
|
355
|
+
});
|
@@ -0,0 +1,80 @@
|
|
1
|
+
var require = patchRequire(require);
|
2
|
+
|
3
|
+
var fs = require('fs');
|
4
|
+
var AppleBot = require('applebot').AppleBot;
|
5
|
+
var CommandHandler = require('applebot').CommandHandler;
|
6
|
+
|
7
|
+
var commandHandler = new CommandHandler("create_app_id.js");
|
8
|
+
|
9
|
+
var userOptions = commandHandler.parseArgs();
|
10
|
+
var applebot = new AppleBot(commandHandler.getAuthFromArgs());
|
11
|
+
|
12
|
+
var LOAD_URL = "https://developer.apple.com/account/ios/identifiers/bundle/bundleCreate.action";
|
13
|
+
|
14
|
+
applebot.openPage(LOAD_URL, function(page){
|
15
|
+
applebot.action("Fill out App ID form", function() {
|
16
|
+
var fillOptions = {};
|
17
|
+
fillOptions['appIdName'] = userOptions.name;
|
18
|
+
if (userOptions.app_id.indexOf("*") === -1) {
|
19
|
+
fillOptions['type'] = 'explicit';
|
20
|
+
fillOptions['explicitIdentifier'] = userOptions.app_id;
|
21
|
+
}
|
22
|
+
else {
|
23
|
+
fillOptions['type'] = 'wildcard';
|
24
|
+
fillOptions['wildcardIdentifier'] = userOptions.app_id;
|
25
|
+
}
|
26
|
+
|
27
|
+
if (userOptions.data_protection) {
|
28
|
+
fillOptions['dataProtectionPermission'] = true;
|
29
|
+
var dataProtectionToName = function(dataProtection) {
|
30
|
+
return {
|
31
|
+
complete: 'complete',
|
32
|
+
unless_option: 'unlessopen',
|
33
|
+
until_first_auth: 'untilfirstauth'
|
34
|
+
}[dataProtection];
|
35
|
+
};
|
36
|
+
fillOptions['dataProtectionPermissionLevel'] = dataProtectionToName(userOptions.data_protection);
|
37
|
+
}
|
38
|
+
|
39
|
+
var services = ['icloud', 'inter_app_audio', 'passbook', 'push'];
|
40
|
+
var serviceToName = function(service) {
|
41
|
+
return {
|
42
|
+
icloud: 'iCloud',
|
43
|
+
inter_app_audio: 'IAD53UNK2F',
|
44
|
+
passbook: 'pass',
|
45
|
+
push: 'push'
|
46
|
+
}[service];
|
47
|
+
};
|
48
|
+
for (var i = 0; i < services.length; i++) {
|
49
|
+
var service = services[i];
|
50
|
+
if(userOptions[service] && userOptions[service] !== 'false') {
|
51
|
+
fillOptions[serviceToName(service)] = true;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
page.fill('form[name=bundleSave]', fillOptions, false);
|
56
|
+
});
|
57
|
+
|
58
|
+
applebot.action("Click App ID submit button", function() {
|
59
|
+
page.click('.submit');
|
60
|
+
});
|
61
|
+
|
62
|
+
applebot.action("Click the confirm button", function() {
|
63
|
+
page.click('.submit');
|
64
|
+
});
|
65
|
+
|
66
|
+
applebot.step("Wait for the confirmation page", "waitForSelector", 'form[name=bundleSubmit]', function() {
|
67
|
+
applebot.action("Click the confirm button");
|
68
|
+
}, function() {
|
69
|
+
page.debugHTML();
|
70
|
+
});
|
71
|
+
|
72
|
+
applebot.step("Wait for a completed form", 'waitForSelector', '.ios.bundles.confirmForm.complete', function() {
|
73
|
+
// Goood to go
|
74
|
+
}, function() {
|
75
|
+
page.debugHTML();
|
76
|
+
});
|
77
|
+
|
78
|
+
applebot.action("Fill out App ID form");
|
79
|
+
applebot.action("Click App ID submit button");
|
80
|
+
});
|
@@ -0,0 +1,134 @@
|
|
1
|
+
var require = patchRequire(require);
|
2
|
+
|
3
|
+
var fs = require('fs');
|
4
|
+
var AppleBot = require('applebot').AppleBot;
|
5
|
+
var CommandHandler = require('applebot').CommandHandler;
|
6
|
+
|
7
|
+
var commandHandler = new CommandHandler("create_profile.js");
|
8
|
+
|
9
|
+
|
10
|
+
var userOptions = commandHandler.parseArgs();
|
11
|
+
var applebot = new AppleBot(commandHandler.getAuthFromArgs());
|
12
|
+
|
13
|
+
var LOAD_URL = "https://developer.apple.com/account/ios/profile/profileCreate.action";
|
14
|
+
|
15
|
+
applebot.openPage(LOAD_URL, function(page){
|
16
|
+
applebot.action("Select the profile type", function() {
|
17
|
+
var fillOptions = {};
|
18
|
+
if (userOptions.environment === 'development') {
|
19
|
+
fillOptions['distributionType'] = 'limited';
|
20
|
+
}
|
21
|
+
else if (userOptions.environment === 'store') {
|
22
|
+
fillOptions['distributionType'] = 'store';
|
23
|
+
}
|
24
|
+
else if (userOptions.environment === 'adhoc') {
|
25
|
+
fillOptions['distributionType'] = 'adhoc';
|
26
|
+
}
|
27
|
+
else if (userOptions.environment == 'inhouse') {
|
28
|
+
fillOptions['distributionType'] = 'inhouse';
|
29
|
+
}
|
30
|
+
|
31
|
+
page.fill("form[successurl='/account/ios/profile/profileCreateApp.action']", fillOptions, false);
|
32
|
+
page.click('.submit');
|
33
|
+
});
|
34
|
+
|
35
|
+
applebot.action("Select the app ID", function() {
|
36
|
+
var fillOptions = {};
|
37
|
+
|
38
|
+
var value = page.evaluate(function(appId) {
|
39
|
+
var matchId = false;
|
40
|
+
|
41
|
+
var options = $("select[name=appIdId]").children();
|
42
|
+
for (var i = 0; i < options.length; i++) {
|
43
|
+
var option = options[i];
|
44
|
+
if (option.innerHTML.indexOf(appId + ")") !== -1) {
|
45
|
+
matchId = option.value;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
return matchId;
|
50
|
+
}, userOptions.app_id);
|
51
|
+
|
52
|
+
if (value === false) {
|
53
|
+
page.die("Error: Could not find App ID option");
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
fillOptions['appIdId'] = value;
|
57
|
+
}
|
58
|
+
|
59
|
+
page.fill("form[successurl='/account/ios/profile/profileCreateCertificates.action']", fillOptions, false);
|
60
|
+
page.click('.submit');
|
61
|
+
});
|
62
|
+
|
63
|
+
applebot.action("Select the certificate", function() {
|
64
|
+
var fillOptions = {};
|
65
|
+
var certificateValue = page.evaluate(function(certificate) {
|
66
|
+
if (certificate === void(0)) {
|
67
|
+
return $(".validate").first().val();
|
68
|
+
}
|
69
|
+
var value = false;
|
70
|
+
|
71
|
+
var options = $(".distribution .rows");
|
72
|
+
for (var i = 0; i < options.length; i++) {
|
73
|
+
var option = options[i];
|
74
|
+
if ($(".title", option).text() == certificate) {
|
75
|
+
value = $("input", option).val()
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
return value;
|
80
|
+
}, userOptions.certificate);
|
81
|
+
|
82
|
+
if (certificateValue === false) {
|
83
|
+
page.die("Error: Could not find matching certificate");
|
84
|
+
}
|
85
|
+
else {
|
86
|
+
fillOptions['certificateIds'] = certificateValue;
|
87
|
+
}
|
88
|
+
page.fill("form[successurl='/account/ios/profile/profileCreateName.action']", fillOptions, false);
|
89
|
+
page.click('.submit');
|
90
|
+
});
|
91
|
+
|
92
|
+
applebot.action("Select the provisioning profile name", function() {
|
93
|
+
var fillOptions = {
|
94
|
+
'provisioningProfileName': userOptions.name
|
95
|
+
};
|
96
|
+
page.fill("form[successurl='/account/ios/profile/profileDownload.action?provisioningProfileId=']", fillOptions, false);
|
97
|
+
page.click('.submit');
|
98
|
+
});
|
99
|
+
|
100
|
+
applebot.action("Download profile", function() {
|
101
|
+
var downloadUrl = page.evaluate(function() {
|
102
|
+
return $(".blue").attr('href');
|
103
|
+
});
|
104
|
+
page.download(downloadUrl, userOptions.download_to);
|
105
|
+
});
|
106
|
+
|
107
|
+
applebot.step("Wait to pick bundle ID", 'waitForSelector', "form[successurl='/account/ios/profile/profileCreateCertificates.action']", function() {
|
108
|
+
applebot.action("Select the app ID");
|
109
|
+
});
|
110
|
+
|
111
|
+
applebot.step("Wait to pick bundle certificate", 'waitForSelector', "form[successurl='/account/ios/profile/profileCreateName.action']", function() {
|
112
|
+
applebot.action("Select the certificate");
|
113
|
+
});
|
114
|
+
|
115
|
+
applebot.step("Wait to pick profile name", 'waitForSelector', "form[successurl='/account/ios/profile/profileDownload.action?provisioningProfileId=']", function() {
|
116
|
+
applebot.action("Select the provisioning profile name");
|
117
|
+
});
|
118
|
+
|
119
|
+
applebot.step("Wait for profile to generate", 'waitForText', 'Your provisioning profile is ready.', function() {
|
120
|
+
if (userOptions.download_to) {
|
121
|
+
applebot.action("Download profile");
|
122
|
+
}
|
123
|
+
|
124
|
+
page.echo("Success").exit();
|
125
|
+
}, {
|
126
|
+
onFail: function() {
|
127
|
+
page.debugHTML();
|
128
|
+
},
|
129
|
+
timeout: 10 * 1000
|
130
|
+
});
|
131
|
+
|
132
|
+
// Start
|
133
|
+
applebot.action("Select the profile type");
|
134
|
+
});
|
@@ -0,0 +1,57 @@
|
|
1
|
+
var require = patchRequire(require);
|
2
|
+
|
3
|
+
var fs = require('fs');
|
4
|
+
var AppleBot = require('applebot').AppleBot;
|
5
|
+
var CommandHandler = require('applebot').CommandHandler;
|
6
|
+
|
7
|
+
var commandHandler = new CommandHandler("delete_app_id.js");
|
8
|
+
|
9
|
+
|
10
|
+
var userOptions = commandHandler.parseArgs();
|
11
|
+
var applebot = new AppleBot(commandHandler.getAuthFromArgs());
|
12
|
+
|
13
|
+
var LOAD_URL = "https://developer.apple.com/account/ios/identifiers/bundle/bundleList.action";
|
14
|
+
|
15
|
+
applebot.openPage(LOAD_URL, function(page){
|
16
|
+
page.waitForSelector('form[name=bundleEdit]', function() {
|
17
|
+
this.click('.remove-button');
|
18
|
+
}, function() {
|
19
|
+
this.die("Error: Could not find edit form", 1);
|
20
|
+
});
|
21
|
+
page.waitForSelector('.red', function() {
|
22
|
+
this.click('.red');
|
23
|
+
}, function() {
|
24
|
+
this.die("Error: Could not find delete button", 1);
|
25
|
+
});
|
26
|
+
page.waitForUrl(LOAD_URL, function() {
|
27
|
+
this.echo("Success").exit();
|
28
|
+
}, function() {
|
29
|
+
this.die("Error: Did not finish delete", 1);
|
30
|
+
});
|
31
|
+
|
32
|
+
var clickCorrectElement = function(appId) {
|
33
|
+
var rows = document.getElementsByClassName('ui-widget-content jqgrow ui-row-ltr');
|
34
|
+
var match = undefined;
|
35
|
+
for (var i = 0; i < rows.length; i++) {
|
36
|
+
var row = rows[i];
|
37
|
+
for (var j = 0; j < row.children.length; j++) {
|
38
|
+
var child = row.children[j];
|
39
|
+
if (child.title == appId) {
|
40
|
+
match = child;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
if (match) {
|
45
|
+
$(match.parentNode).click();
|
46
|
+
$('.edit-button').click();
|
47
|
+
return true;
|
48
|
+
}
|
49
|
+
else {
|
50
|
+
return false;
|
51
|
+
}
|
52
|
+
};
|
53
|
+
var resultId = page.evaluate(clickCorrectElement, userOptions.app_id);
|
54
|
+
if (resultId === false) {
|
55
|
+
page.die("Error: could not find App Id");
|
56
|
+
}
|
57
|
+
});
|
@@ -0,0 +1,36 @@
|
|
1
|
+
var require = patchRequire(require);
|
2
|
+
|
3
|
+
var fs = require('fs');
|
4
|
+
var AppleBot = require('applebot').AppleBot;
|
5
|
+
var CommandHandler = require('applebot').CommandHandler;
|
6
|
+
|
7
|
+
var commandHandler = new CommandHandler("download_profile.js");
|
8
|
+
|
9
|
+
var userOptions = commandHandler.parseArgs();
|
10
|
+
var applebot = new AppleBot(commandHandler.getAuthFromArgs());
|
11
|
+
|
12
|
+
var profileType = {
|
13
|
+
development: 'limited',
|
14
|
+
distribution: 'production'
|
15
|
+
}[userOptions.profile_type || "development"];
|
16
|
+
|
17
|
+
var LOAD_URL = "https://developer.apple.com/account/ios/profile/profileList.action?type=" + profileType;
|
18
|
+
|
19
|
+
applebot.openPage(LOAD_URL, function(page){
|
20
|
+
var profiles = {};
|
21
|
+
|
22
|
+
applebot.shortcuts.waitToParseProfiles(applebot, page, profileType, function(parsedProfiles) {
|
23
|
+
profiles = parsedProfiles;
|
24
|
+
applebot.action("Download profile");
|
25
|
+
});
|
26
|
+
|
27
|
+
applebot.action("Download profile", function() {
|
28
|
+
var profile = profiles[userOptions.app_id];
|
29
|
+
if (!profile) {
|
30
|
+
page.die("Could not find profile for app ID " + userOptions.app_id);
|
31
|
+
}
|
32
|
+
else {
|
33
|
+
page.download(profile.download_url, userOptions.download_to);
|
34
|
+
}
|
35
|
+
});
|
36
|
+
});
|