771 lines
20 KiB
Haxe
771 lines
20 KiB
Haxe
package utils.publish;
|
|
|
|
import haxe.crypto.Base64;
|
|
import hxp.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;
|
|
|
|
System.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)
|
|
{
|
|
System.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("");
|
|
System.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": System.openURL (urlContentRatings);
|
|
case "2": System.openURL (devUrlApp);
|
|
case "3": System.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("");
|
|
System.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";
|
|
}
|