862 lines
20 KiB
Haxe
862 lines
20 KiB
Haxe
package utils.publish;
|
|
|
|
|
|
import haxe.crypto.Base64;
|
|
import haxe.io.Path;
|
|
import haxe.Json;
|
|
import lime.tools.helpers.CLIHelper;
|
|
import lime.tools.helpers.Log;
|
|
import lime.tools.helpers.ZipHelper;
|
|
import lime.tools.helpers.ProcessHelper;
|
|
import lime.graphics.Image;
|
|
import lime.net.oauth.*;
|
|
import lime.net.*;
|
|
import lime.project.HXProject;
|
|
import utils.PlatformSetup;
|
|
import sys.FileSystem;
|
|
import sys.io.File;
|
|
|
|
|
|
class FirefoxMarketplace {
|
|
|
|
|
|
private static function compress (project:HXProject):String {
|
|
|
|
var outputDirectory = project.app.path + "/firefox";
|
|
var source = outputDirectory + "/bin/";
|
|
var packagedFile = project.app.file + ".zip";
|
|
var destination = outputDirectory + "/dist/" + packagedFile;
|
|
|
|
ZipHelper.compress (source, destination);
|
|
|
|
return destination;
|
|
|
|
}
|
|
|
|
|
|
public static function isValid (project:HXProject):Bool {
|
|
|
|
var result = FirefoxHelper.validate (project);
|
|
|
|
if (result.errors.length != 0) {
|
|
|
|
var errorMsg = "The application cannot be published\n";
|
|
|
|
for (error in result.errors) {
|
|
|
|
errorMsg += '\n * ' + error;
|
|
|
|
}
|
|
|
|
if (Log.verbose) Log.println ("");
|
|
Log.error (errorMsg);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
public static function publish (project:HXProject):Void {
|
|
|
|
var devServer = project.targetFlags.exists ("dev");
|
|
var forceUpload = project.targetFlags.exists ("force");
|
|
var answer:Answer;
|
|
|
|
/*if (!devServer) {
|
|
|
|
Log.println ("In which server do you want to publish your application?");
|
|
Log.println ("\t1. Production server.");
|
|
Log.println ("\t2. Development server.");
|
|
Log.println ("\tq. Quit.");
|
|
|
|
answer = CLIHelper.ask ("Which server?", ["1", "2", "q"]);
|
|
|
|
switch (answer) {
|
|
|
|
case CUSTOM (x):
|
|
|
|
switch (x) {
|
|
|
|
case "2": devServer = true;
|
|
case "q": Sys.exit (0);
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
Log.info ("Checking account...");
|
|
|
|
var defines = project.defines;
|
|
var existsProd = defines.exists ("FIREFOX_MARKETPLACE_KEY") && defines.exists ("FIREFOX_MARKETPLACE_SECRET");
|
|
var existsDev = defines.exists ("FIREFOX_MARKETPLACE_DEV_KEY") && defines.exists ("FIREFOX_MARKETPLACE_DEV_SECRET");
|
|
|
|
if ((!existsProd && !devServer) || (!existsDev && devServer)) {
|
|
|
|
setup (false, devServer, cast defines);
|
|
|
|
// we need to get all the defines after configuring the account
|
|
Log.mute = true;
|
|
defines = PlatformSetup.getDefines ();
|
|
Log.mute = false;
|
|
|
|
}
|
|
|
|
var baseUrl = devServer ? FirefoxHelper.DEVELOPMENT_SERVER_URL : FirefoxHelper.PRODUCTION_SERVER_URL;
|
|
var appID:Int = -1;
|
|
var appSlug:String = "";
|
|
var appName = project.meta.title;
|
|
|
|
var key = defines.get ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "KEY");
|
|
var secret = defines.get ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "SECRET");
|
|
|
|
var marketplace = new MarketplaceAPI (key, secret, devServer);
|
|
|
|
var error = function (r:Dynamic) {
|
|
|
|
Reflect.deleteField (r, "error");
|
|
//Log.println ("");
|
|
Log.error ((r.customError != null ? r.customError : 'There was an error:\n\n$r'));
|
|
|
|
};
|
|
|
|
var response:Dynamic = marketplace.getUserAccount ();
|
|
|
|
if (response.error) {
|
|
|
|
response.customError = "Could not validate your account, please verify your account information";
|
|
error (response);
|
|
|
|
}
|
|
|
|
//Log.println ("OK");
|
|
|
|
var apps:List<Dynamic> = Lambda.filter (marketplace.getUserApps (), function(obj) return appName == Reflect.field (obj.name, "en-US"));
|
|
|
|
if (!forceUpload && apps.length > 0) {
|
|
|
|
var app = apps.first ();
|
|
|
|
Log.println ("This application has already been submitted to the Firefox Marketplace.");
|
|
answer = CLIHelper.ask ("Do you want to open the edit page?", ["y", "n"]);
|
|
|
|
if (answer == YES) {
|
|
|
|
ProcessHelper.openURL (baseUrl + '/developers/app/${app.slug}/edit');
|
|
|
|
}
|
|
|
|
Sys.exit (0);
|
|
|
|
}
|
|
|
|
//Log.println ("Submitting \"" + appName + "\" to the Firefox " + (devServer ? "development" : "production") + " server");
|
|
|
|
var packagedFile = compress (project);
|
|
|
|
response = marketplace.submitForValidation (packagedFile);
|
|
|
|
if (response.error || response.id == null) {
|
|
|
|
error (response);
|
|
|
|
}
|
|
|
|
var uploadID = response.id;
|
|
|
|
Log.println ("");
|
|
//Log.print ('Server validation ($uploadID)');
|
|
Log.print ("Waiting for server");
|
|
|
|
do {
|
|
|
|
Log.print (".");
|
|
response = marketplace.checkValidationStatus (uploadID);
|
|
Sys.sleep (1);
|
|
|
|
} while (!response.processed);
|
|
|
|
Log.println ("");
|
|
|
|
if (response.valid) {
|
|
|
|
//Log.println (" VALID");
|
|
Log.info ("Sending application details...");
|
|
response = marketplace.createApp (uploadID);
|
|
|
|
if (response.error || response.id == null) {
|
|
|
|
//Log.println ("ERROR");
|
|
error (response);
|
|
|
|
}
|
|
|
|
appID = response.id;
|
|
appSlug = response.slug;
|
|
|
|
//Log.println ("OK");
|
|
//Log.print ("Updating application information... ");
|
|
response = marketplace.updateAppInformation (appID, project);
|
|
|
|
if (response.error) {
|
|
|
|
//Log.println ("ERROR");
|
|
error (response);
|
|
|
|
}
|
|
|
|
//Log.println ("OK");
|
|
//Log.println ("Updating screenshots:");
|
|
|
|
var screenshots:Array<String> = project.config.getArrayString ("firefox-marketplace.screenshots.screenshot", "path");
|
|
|
|
for (i in 0...screenshots.length) {
|
|
|
|
response = marketplace.uploadScreenshot (appID, i, screenshots[i]);
|
|
Log.println ("");
|
|
|
|
if (response.error) {
|
|
|
|
error (response);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var urlApp = baseUrl + '/app/$appSlug/';
|
|
var devUrlApp = baseUrl + '/developers/app/$appSlug/';
|
|
var urlContentRatings = devUrlApp + "content_ratings/edit";
|
|
|
|
var havePayments = project.config.getString ("firefox-marketplace.premium-type", "free") != cast PremiumType.FREE;
|
|
|
|
Log.println ("");
|
|
Log.info ("Application submitted!");
|
|
Sys.sleep (1);
|
|
Log.println ("");
|
|
Log.info ("Before the application is fully published, you will need to fill out a content");
|
|
Log.info ("rating questionnaire, and send the application for review");
|
|
Log.println ("");
|
|
var answer = CLIHelper.ask ("Would you like to complete your submission now?");
|
|
|
|
if (answer == YES || answer == ALWAYS) {
|
|
|
|
if (Log.verbose) Log.println ("");
|
|
ProcessHelper.openURL (urlContentRatings);
|
|
|
|
} else {
|
|
|
|
Log.println ("");
|
|
Log.info ("You can complete your submission later by going to " + devUrlApp);
|
|
|
|
}
|
|
|
|
/*
|
|
Log.println ("");
|
|
Log.warn ("Before this application can be reviewed & published:");
|
|
Log.warn ("* You will need to fill the contents rating questionnaire *");
|
|
|
|
if (havePayments) Log.warn ("* You will need to add or link a payment account *");
|
|
|
|
Log.println ("");
|
|
Log.println ("1. Open the contents rating questionnaire page.");
|
|
Log.println ("2. Open the application edit page.");
|
|
Log.println ("3. Open the application listing page.");
|
|
Log.println ("q. I'm fine, thanks.");
|
|
|
|
answer = CLIHelper.ask ("Open the questionnaire now?", ["1", "2", "3", "q"]);
|
|
|
|
switch (answer) {
|
|
|
|
case CUSTOM (x):
|
|
|
|
switch (x) {
|
|
|
|
case "1": ProcessHelper.openURL (urlContentRatings);
|
|
case "2": ProcessHelper.openURL (devUrlApp);
|
|
case "3": ProcessHelper.openURL (urlApp);
|
|
case _:
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
|
|
}
|
|
|
|
Log.println ("");
|
|
Log.println ("Your application listing page is:");
|
|
Log.println ('$urlApp');
|
|
Log.println ("");
|
|
Log.println ("Goodbye!");*/
|
|
|
|
} else {
|
|
|
|
//Log.println (" FAILED");
|
|
Log.println ("");
|
|
|
|
var errorMsg = "Application failed server validation";
|
|
|
|
var errors:List<Dynamic> = Lambda.filter (response.validation.messages, function(m) return m.type == "error");
|
|
var n = 1;
|
|
|
|
for (error in errors) {
|
|
|
|
errorMsg += ('\n * ${error.description.join (" ")}');
|
|
|
|
}
|
|
|
|
//errorMsg += "\nPlease refer to the documentation to fix the issues.";
|
|
marketplace.close ();
|
|
Log.error (errorMsg);
|
|
|
|
}
|
|
|
|
marketplace.close();
|
|
|
|
}
|
|
|
|
|
|
public static function setup (askServer:Bool = true, devServer:Bool = false, defines:Map<String, String> = null):Void {
|
|
|
|
if (defines == null) {
|
|
|
|
defines = PlatformSetup.getDefines ();
|
|
|
|
}
|
|
|
|
var existsProd = defines.exists ("FIREFOX_MARKETPLACE_KEY") && defines.exists ("FIREFOX_MARKETPLACE_SECRET");
|
|
var existsDev = defines.exists ("FIREFOX_MARKETPLACE_DEV_KEY") && defines.exists ("FIREFOX_MARKETPLACE_DEV_SECRET");
|
|
|
|
// TODO warning about the override of the account
|
|
|
|
Log.println ("You need to link your developer account to publish to the Firefox Marketplace");
|
|
var answer = CLIHelper.ask ("Would you like to open the developer site now?");
|
|
|
|
if (answer == YES || answer == ALWAYS) {
|
|
|
|
var server = "";
|
|
|
|
/*if (askServer) {
|
|
|
|
Log.println ("");
|
|
Log.println ("First of all you need to select the server you want to setup your account.");
|
|
Log.println ("Each server has its own configuration and can't be shared.");
|
|
Log.println ("\t1. Production server (" + FirefoxHelper.PRODUCTION_SERVER_URL + ")");
|
|
Log.println ("\t2. Development server (" + FirefoxHelper.DEVELOPMENT_SERVER_URL + ")");
|
|
Log.println("\tq. Cancel");
|
|
answer = CLIHelper.ask ("Choose the server to setup your Firefox Marketplace account.", ["1", "2", "q"]);
|
|
|
|
} else {*/
|
|
|
|
answer = devServer ? CUSTOM ("2") : CUSTOM ("1");
|
|
|
|
//}
|
|
|
|
switch (answer) {
|
|
|
|
case CUSTOM ("1"):
|
|
|
|
server = FirefoxHelper.PRODUCTION_SERVER_URL;
|
|
devServer = false;
|
|
|
|
case CUSTOM ("2"):
|
|
|
|
server = FirefoxHelper.DEVELOPMENT_SERVER_URL;
|
|
devServer = true;
|
|
|
|
default: Sys.exit (0);
|
|
|
|
}
|
|
|
|
/*if ((existsProd && !devServer) || (existsDev && devServer)) {
|
|
|
|
Log.info ("");
|
|
Log.warn ("You will override your account settings!");
|
|
answer = CLIHelper.ask ("Are you sure?", ["y", "n"]);
|
|
|
|
if (answer == NO) {
|
|
|
|
Sys.exit (0);
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
Log.println ("");
|
|
Log.info ("Opening \"" + server + "/developers/api\"...");
|
|
Log.println ("");
|
|
Log.info (" * Create a new account or login");
|
|
Log.info (" * Choose \"Command line\" as the client type then press \"Create\"");
|
|
|
|
Sys.sleep (3);
|
|
if (Log.verbose) Log.println ("");
|
|
ProcessHelper.openURL (server + "/developers/api");
|
|
Sys.sleep (2);
|
|
|
|
Log.println ("");
|
|
Log.info ("\x1b[1mPress any key to continue\x1b[0m");
|
|
|
|
try {
|
|
|
|
Sys.stdin ().readLine ();
|
|
|
|
} catch (e:Dynamic) {
|
|
|
|
Sys.exit (0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var key = StringTools.trim (CLIHelper.param ("OAuth Key"));
|
|
var secret = StringTools.trim (CLIHelper.param ("OAuth Secret"));
|
|
|
|
Log.println ("");
|
|
|
|
var marketplace = new MarketplaceAPI (key, secret, devServer);
|
|
var name:String = "";
|
|
var account:Dynamic;
|
|
var valid = false;
|
|
|
|
do {
|
|
|
|
Log.println ("Checking account...");
|
|
account = marketplace.getUserAccount ();
|
|
|
|
if (account != null && account.display_name != null) {
|
|
|
|
name = account.display_name;
|
|
valid = true;
|
|
|
|
}
|
|
|
|
if (!valid) {
|
|
|
|
Log.println ("There was a problem connecting to your developer account");
|
|
answer = CLIHelper.ask ("Would you like to try again?");
|
|
|
|
if (answer == YES) {
|
|
|
|
Log.println ("");
|
|
key = StringTools.trim (CLIHelper.param ("OAuth Key"));
|
|
secret = StringTools.trim (CLIHelper.param ("OAuth Secret"));
|
|
Log.println ("");
|
|
|
|
marketplace.client.consumer.key = key;
|
|
marketplace.client.consumer.secret = secret;
|
|
|
|
} else {
|
|
|
|
marketplace.close ();
|
|
Sys.exit (0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (!valid);
|
|
|
|
Log.println ("Hello " + name + "!");
|
|
|
|
Log.mute = true;
|
|
defines = PlatformSetup.getDefines ();
|
|
Log.mute = false;
|
|
|
|
defines.set ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "KEY", key);
|
|
defines.set ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "SECRET", secret);
|
|
|
|
PlatformSetup.writeConfig (defines.get ("LIME_CONFIG"), defines);
|
|
Log.println ("");
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
class FirefoxHelper {
|
|
|
|
|
|
public static inline var PRODUCTION_SERVER_URL = "https://marketplace.firefox.com";
|
|
public static inline var DEVELOPMENT_SERVER_URL = "https://marketplace-dev.allizom.org";
|
|
|
|
private static inline var TITLE_MAX_CHARS = 127;
|
|
private static inline var MAX_CATEGORIES = 2;
|
|
private static var MIN_WH_SCREENSHOT = { width: 320, height: 480 };
|
|
|
|
|
|
private static function isScreenshotValid (path:String):Bool {
|
|
|
|
if (FileSystem.exists (path)) {
|
|
|
|
var img = Image.fromFile (path);
|
|
var portrait = img.width >= MIN_WH_SCREENSHOT.width && img.height >= MIN_WH_SCREENSHOT.height;
|
|
var landscape = img.width >= MIN_WH_SCREENSHOT.height && img.height >= MIN_WH_SCREENSHOT.width;
|
|
return portrait || landscape;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
public static function validate (project:HXProject):{ errors:Array<String>, warnings:Array<String> } {
|
|
|
|
var errors:Array<String> = [];
|
|
var warnings:Array<String> = [];
|
|
|
|
// We will check if the project has the minimal required fields for publishing to the Firefox Marketplace
|
|
|
|
if (project.meta.title == "") {
|
|
|
|
errors.push ("You need to have a title\n\n\t<meta title=\"Hello World\"/>\n");
|
|
|
|
}
|
|
|
|
if (project.meta.title.length > TITLE_MAX_CHARS) {
|
|
|
|
errors.push ("Your title is too long (max " + TITLE_MAX_CHARS + " characters)\n");
|
|
|
|
}
|
|
|
|
if (project.config.getString ("firefox-marketplace.description", project.meta.description) == "") {
|
|
|
|
errors.push ("You need to have a description\n\n\t<meta description=\"My description\"/>\n");
|
|
|
|
}
|
|
|
|
if (project.meta.company == "") {
|
|
|
|
errors.push ("You need to have a company name\n\n\t<meta company=\"Company Name\"/>\n");
|
|
|
|
}
|
|
|
|
if (project.meta.companyUrl == "") {
|
|
|
|
errors.push ("You need to have a company URL\n\n\t<meta company-url=\"http://www.company.com\"/>\n");
|
|
|
|
}
|
|
|
|
var categories = project.config.getArrayString ("firefox-marketplace.categories.category", "name");
|
|
|
|
if (categories.length == 0) {
|
|
|
|
errors.push ("You need to have at least one category\n\n\t<config type=\"firefox-marketplace\">\n\t <categories>\n\t <category name=\"games\"/>\n\t </categories>\n\t</config>\n");
|
|
|
|
} else if (categories.length > MAX_CATEGORIES) {
|
|
|
|
errors.push ("You cannot have more than two categories");
|
|
|
|
}
|
|
|
|
if (project.config.getString ("firefox-marketplace.privacyPolicy") == "") {
|
|
|
|
errors.push ("You need to have a privacy policy\n\n\t<config type=\"firefox-marketplace\">\n\t <privacyPolicy>Policy detail</privacyPolicy>\n\t</config>\n");
|
|
|
|
}
|
|
|
|
if (project.config.getString ("firefox-marketplace.support.email") == "") {
|
|
|
|
errors.push ("You need to have a support email address\n\n\t<config type=\"firefox-marketplace\">\n\t <support email=\"support@company.com\"/>\n\t</config>\n");
|
|
|
|
}
|
|
|
|
var screenshots = project.config.getArrayString ("firefox-marketplace.screenshots.screenshot", "path");
|
|
|
|
if (screenshots.length == 0) {
|
|
|
|
errors.push ("You need to have at least one screenshot\n\n\t<config type=\"firefox-marketplace\">\n\t <screenshots>\n\t <screenshot path=\"screenshot.png\"/>\n\t </screenshots>\n\t</config>\n");
|
|
|
|
} else {
|
|
|
|
for (path in screenshots) {
|
|
|
|
if (!isScreenshotValid (path)) {
|
|
|
|
if (!FileSystem.exists (path)) {
|
|
|
|
errors.push ("Screenshot \"" + Path.withoutDirectory (path) + "\" does not exist\n");
|
|
|
|
} else {
|
|
|
|
errors.push ("Screenshot \"" + Path.withoutDirectory (path) + "\" must be at least 320 x 480 in size\n");
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return { errors: errors, warnings: warnings };
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
class MarketplaceAPI {
|
|
|
|
|
|
private static inline var API_PATH = "/api/v1/";
|
|
|
|
public var client:OAuthClient;
|
|
|
|
private var loader:URLLoader;
|
|
private var entryPoint:String;
|
|
|
|
|
|
public function new (key:String = null, secret:String = null, devServer:Bool = false) {
|
|
|
|
loader = new URLLoader ();
|
|
|
|
if (key != null && secret != null) {
|
|
|
|
client = new OAuthClient (OAuthVersion.V1, new OAuthConsumer (key, secret));
|
|
|
|
}
|
|
|
|
entryPoint = (devServer ? FirefoxHelper.DEVELOPMENT_SERVER_URL : FirefoxHelper.PRODUCTION_SERVER_URL) + API_PATH;
|
|
|
|
}
|
|
|
|
|
|
public function checkValidationStatus (uploadID:String):Dynamic {
|
|
|
|
var response = load (GET, 'apps/validation/$uploadID/', null);
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
public function close ():Void {
|
|
|
|
loader.close ();
|
|
|
|
}
|
|
|
|
|
|
public function createApp (uploadID:String):Dynamic {
|
|
|
|
var response = load (POST, 'apps/app/', Json.stringify ({ upload: uploadID }));
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
public function customRequest (method:URLRequestMethod, path:String, ?data:Dynamic):URLRequest {
|
|
|
|
var request:URLRequest;
|
|
|
|
if (client == null) {
|
|
|
|
request = new URLRequest (entryPoint + path);
|
|
|
|
} else {
|
|
|
|
request = client.createRequest (method, entryPoint + path);
|
|
|
|
}
|
|
|
|
request.method = method;
|
|
request.data = data;
|
|
request.contentType = "application/json";
|
|
|
|
return request;
|
|
|
|
}
|
|
|
|
|
|
public function getUserAccount():Dynamic {
|
|
|
|
var response = load (GET, "account/settings/mine/", null);
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
public function getUserApps ():Array<Dynamic> {
|
|
|
|
var result:Array<Dynamic> = [];
|
|
var response = load (GET, 'apps/app/', null);
|
|
|
|
if (!response.error && response.objects != null) {
|
|
|
|
for (obj in cast (response.objects, Array<Dynamic>)) {
|
|
|
|
result.push (obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
private function load (method:URLRequestMethod, path:String, data:String = null, progressMsg:String = null):Dynamic {
|
|
|
|
var response:Dynamic = {};
|
|
var status = 0;
|
|
var request = customRequest (method, path, data);
|
|
var withProgress = progressMsg != null && progressMsg.length > 0 && data != null;
|
|
|
|
var uploadingFunc:URLLoader->Int->Int->Void = null;
|
|
|
|
if (withProgress) {
|
|
|
|
uploadingFunc = function (l, up, dl) CLIHelper.progress ('$progressMsg', up, data.length);
|
|
loader.onProgress.add (uploadingFunc);
|
|
|
|
}
|
|
|
|
loader.onHTTPStatus.add (function (_, s) status = s, true);
|
|
|
|
loader.onComplete.add (
|
|
function (l) {
|
|
|
|
response = Json.parse (l.data);
|
|
|
|
if (withProgress)
|
|
l.onProgress.remove (uploadingFunc);
|
|
|
|
}
|
|
, true);
|
|
|
|
loader.load (request);
|
|
|
|
response.error = false;
|
|
|
|
if (status >= 400) {
|
|
|
|
response.error = true;
|
|
|
|
}
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
public function submitForValidation (path:String, type:String = "application/zip"):Dynamic {
|
|
|
|
var p = new Path (path);
|
|
var response:Dynamic = {};
|
|
|
|
if (FileSystem.exists (path) && p.ext == "zip") {
|
|
|
|
var base = Base64.encode (File.getBytes (path));
|
|
var filename = p.file + "." + p.ext;
|
|
|
|
var upload = {
|
|
upload: {
|
|
type: type,
|
|
name: filename,
|
|
data: base
|
|
}
|
|
};
|
|
|
|
response = load (POST, "apps/validation/", Json.stringify (upload), "Uploading:");
|
|
|
|
} else {
|
|
|
|
response.error = true;
|
|
response.customError = 'File $path doesn\'t exist';
|
|
|
|
}
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
public function updateAppInformation (appID:Int, project:HXProject):Dynamic {
|
|
|
|
var object = {
|
|
name: project.meta.title,
|
|
categories: project.config.getArrayString ("firefox-marketplace.categories.category", "name"),
|
|
description: project.config.getString ("firefox-marketplace.description", project.meta.description),
|
|
privacy_policy: project.config.getString ("firefox-marketplace.privacyPolicy"),
|
|
homepage: project.config.getString ("firefox-marketplace.homepage"),
|
|
support_url: project.config.getString ("firefox-marketplace.support.url"),
|
|
support_email: project.config.getString ("firefox-marketplace.support.email"),
|
|
device_types:project.config.getArrayString ("firefox-marketplace.devices.device", "type", [ "firefoxos", "desktop" ]),
|
|
premium_type: project.config.getString ("firefox-marketplace.premium-type", "free"),
|
|
price: project.config.getString ("firefox-marketplace.config.price", "0.99"),
|
|
};
|
|
|
|
var response = load (PUT, 'apps/app/$appID/', Json.stringify (object));
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
public function uploadScreenshot (appID:Int, position:Int, path:String):Dynamic {
|
|
|
|
var response:Dynamic = {};
|
|
|
|
if (FileSystem.exists (path)) {
|
|
|
|
var p = new Path (path);
|
|
var type = p.ext == "png" ? "image/png" : "image/jpeg";
|
|
var base = Base64.encode (File.getBytes (path));
|
|
var filename = p.file + "." + p.ext;
|
|
|
|
var screenshot = {
|
|
position: position,
|
|
file: {
|
|
type: type,
|
|
name: filename,
|
|
data: base,
|
|
}
|
|
};
|
|
|
|
response = load (POST, 'apps/app/$appID/preview/', Json.stringify (screenshot), 'Uploading screenshot:');
|
|
|
|
} else {
|
|
|
|
response.error = true;
|
|
response.customError = 'File "$path" does not exist';
|
|
|
|
}
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
@:enum abstract DeviceType(String) {
|
|
|
|
var FIREFOXOS = "firefoxos";
|
|
var DESKTOP = "desktop";
|
|
var MOBILE = "mobile";
|
|
var TABLET = "tablet";
|
|
|
|
}
|
|
|
|
|
|
@:enum abstract PremiumType(String) {
|
|
|
|
var FREE = "free";
|
|
var FREE_INAPP = "free-inapp";
|
|
var PREMIUM = "premium";
|
|
var PREMIUM_INAPP = "premium-inapp";
|
|
var OTHER = "other";
|
|
|
|
} |