Skip to content

Instantly share code, notes, and snippets.

@kuFEAR
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save kuFEAR/651bdcdeaeec29de1c29 to your computer and use it in GitHub Desktop.

Select an option

Save kuFEAR/651bdcdeaeec29de1c29 to your computer and use it in GitHub Desktop.
Script to import/export translate resources into mobile platforms (using Google sheets and Google Script)
function onOpen()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var entries1 = [ {name: "Export to mobile resources(Android, iOS)", functionName: "exportTranslates"}];
ss.addMenu("Export to mobile resources(Check your Google Drive)", entries1);
// Danger for now =) just update current spreadsheet
// var entries = [ {name: "Import from Android XML", functionName: "importFromAndroidXml"}];
// ss.addMenu("Import from Android XML", entries);
}
function importFromXml()
{
var fileName = Browser.inputBox("Enter the name of the file in your Google Drive to import (e.g. strings.xml):");
var searchTerm = "title = '"+fileName+"' mimeType = 'text/xml'";
// read more about searching for files at
// https://developers.google.com/apps-script/reference/drive/drive-app#searchFiles(String)
// search for our file
var files = DriveApp.searchFiles(searchTerm)
var xmlFile = "";
// Loop through the results
while (files.hasNext()) {
var file = files.next();
// assuming the first file we find is the one we want
if (file.getName() == fileName) {
// get file as a string
xmlFile = file.getBlob().getDataAsString();
break;
}
}
}
function importFromAndroidXml()
{
var url = Browser.inputBox("Enter the url of english xml resource",
"(e.g. https://dl.dropboxusercontent.com/u/23820726/strings.xml):",
Browser.Buttons.OK_CANCEL);
var ru_url = Browser.inputBox("Enter the url of russian xml resource",
"(e.g. https://dl.dropboxusercontent.com/u/23820726/strings_ru.xml):",
Browser.Buttons.OK_CANCEL);
var xml = UrlFetchApp.fetch(url).getContentText();
var ru_xml = UrlFetchApp.fetch(ru_url).getContentText();
var document = XmlService.parse(xml).getRootElement();
var ru_document = XmlService.parse(ru_xml).getRootElement();
var entries = document.getChildren();
var ru_entries = ru_document.getChildren();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
for (var i = 0; i < entries.length; i++)
{
var name = entries[i].getAttribute('name').getValue();
var en = precheckStringArguments(entries[i].getText());
var ru = '';
for (var j = 0; j < ru_entries.length; j++)
{
var ru_name = ru_entries[j].getAttribute('name').getValue();
if (name == ru_name)
{
ru = precheckStringArguments(ru_entries[j].getText());
}
}
sheet.appendRow([name, en, ru]);
}
}
function exportTranslates()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var startRow = 1;
var startColumn = 1;
var rowCount = sheet.getLastRow();
var columnCount = sheet.getLastColumn();
var xmlAttributeNameIndex = 0;
var sheetValues = sheet.getSheetValues(startRow, startColumn, rowCount, columnCount);
var rootDirName = Browser.inputBox("Enter the name of the root directory to save to Google Drive:");
// start from 1 because 0 (use: xmlAttributeNameIndex)
// column it is attribute 'name' of each item,
// used as ID of string in Mobile Platform as (Android, iOS)
// for get exact string depend of default device locale
for (var language = 1; language < columnCount; language++)
{
// Start poing of one language resource file
var androidDoc = XmlService.createElement('resources');
var iOSDoc = ContentService.createTextOutput();
for (var item = 1; item < rowCount; item++)
{
var text = sheetValues[item][language];
var attrName = sheetValues[item][xmlAttributeNameIndex];
iOSDoc = prepareiOSDoc(attrName, text, iOSDoc);
androidDoc = prepareAndroidXmlDoc(attrName, text, androidDoc);
}
// End point of one language resource file
var xml = XmlService.getPrettyFormat().format(XmlService.createDocument(androidDoc));
var plainText = iOSDoc.getContent();
var languageResourseNamePrefix = sheetValues[0][language];
exportToAndroidXml(xml, languageResourseNamePrefix, rootDirName);
exportToiOS(plainText, languageResourseNamePrefix, rootDirName);
}
showUrlDialog(getTranslateDir(rootDirName));
}
function precheckStringArguments(text)
{
// Add iOS string arguments (s - string, f - decimal digits, d - integer)
// And escape " in \"
text = text.replace(/%@/g, "{s}");
text = text.replace(/%s/g, "{s}");
text = text.replace(/%f/g, "{f}");
text = text.replace(/%d/g, "{d}");
return text;
}
// Prepare the text for iOS text format
function prepareiOSDoc(attrName, text, iOSDoc)
{
// Add iOS string arguments (s - string, f - decimal digits, d - integer)
// And escape '"' in '\"'
text = text.replace(/"/g, "\\\"");
text = text.replace(/{s}/g, "%@");
text = text.replace(/{f}/g, "%f");
text = text.replace(/{d}/g, "%d");
return iOSDoc.append("\"" + attrName + "\"" + "=" + "\"" + text + "\"\;" + '\n');
}
// Prepare the text for Android text format
function prepareAndroidXmlDoc(xmlAttrName, xmlText, androidDoc)
{
var child = XmlService.createElement('string')
.setAttribute('name', xmlAttrName);
// Add Android string arguments (s - string, f - decimal digits, d - integer)
// And escape "'" in "\'"
xmlText = xmlText.replace(/'/g, "\\\'");
xmlText = xmlText.replace(/{s}/g, "%s");
xmlText = xmlText.replace(/{f}/g, "%f");
xmlText = xmlText.replace(/{d}/g, "%d");
if (xmlText.indexOf('%s') != -1 || xmlText.indexOf('%d') != -1 || xmlText.indexOf('%f') != -1) {
child.setAttribute("formatted", false)
}
// Wrap text which contain the char(< > & "), in <![CDATA] text with < > & "]>
if (xmlText.indexOf('<') != -1 || xmlText.indexOf('>') != -1 || xmlText.indexOf('&') != -1 || xmlText.indexOf('"') != -1)
{
var cdata = XmlService.createCdata(xmlText);
child.addContent(cdata);
}
else
{
child.setText(xmlText);
}
androidDoc.addContent(child);
return androidDoc;
}
// Saving Android resources into drive://{rootDirName}/export/android/res/values-{namePrefix}/string.xml
function exportToAndroidXml(document, namePrefix, rootDirName)
{
if ("" === new String(rootDirName).valueOf()) {return;}
var sbDir = getOrCreate(DriveApp.getRootFolder(), rootDirName);
var exportDir = getOrCreate(sbDir,'export');
var resDir = getOrCreate(exportDir,'res');
var valuesDir = getOrCreate(resDir,"values-" + namePrefix);
var fileName = "strings.xml";
recreateFile(valuesDir, fileName, document);
}
// Saving iOS resources into drive://{rootDirName}/export/ios/res/translate/translate_{namePrefix}.strings
function exportToiOS(document, namePrefix, rootDirName)
{
if ("" === new String(rootDirName).valueOf()) {return;}
var sbDir = getOrCreate(DriveApp.getRootFolder(), rootDirName);
var exportDir = getOrCreate(sbDir,'export');
var iOSDir = getOrCreate(exportDir,'ios');
var fileName = "translate_" + namePrefix + ".strings";
recreateFile(iOSDir, fileName, document);
}
function getTranslateDir(rootDirName)
{
var sbDir = getOrCreate(DriveApp.getRootFolder(), rootDirName);
var exportDir = getOrCreate(sbDir,'export');
return exportDir.getUrl();
}
function showUrlDialog(url) {
var app = UiApp.createApplication().setHeight('60').setWidth('200');
app.setTitle(SpreadsheetApp.getActiveSpreadsheet().getName());
var panel = app.createPopupPanel();
var link = app.createAnchor("Google Drive", url);
panel.add(link);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
/**
* File template functions
*/
function getFileByName(dir, fileName)
{
var iterator = dir.getFilesByName(fileName);
if (iterator.hasNext())
{
return iterator.next();
} else {
return null;
}
}
function recreateFile(valuesDir, fileName, document)
{
var iterator = valuesDir.getFilesByName(fileName);
if (iterator.hasNext())
{
valuesDir.removeFile(iterator.next());
}
return valuesDir.createFile(fileName, document);
}
function getOrCreate(folder, folderName)
{
var iterator = folder.getFoldersByName(folderName);
if(iterator.hasNext())
{
return iterator.next();
}
else
{
return folder.createFolder(folderName);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment