Last active
August 29, 2015 14:22
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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