티스토리 뷰

반응형

이 포스팅은 tiii님의 포스팅(http://tiii.tistory.com/22)을 기반으로 작성하였습니다.


제가 직접 돌리면서 부족한 부분과 어려웠던 부분을 나누고자 합니다.


설치 및 시나리오는 참고 사이트를 확인해주세요.


1. 파이썬 설치

https://www.python.org/ftp/python/2.7.11/python-2.7.11.msi

2. 환경변수에 파이썬 Path 추가 (C:\Python27)

   * 윈도우 기준


3. 파이썬에 setuptools, pip, gdata 설치

    Setuptools :
     - https://pypi.python.org/pypi/setuptools/1.0
     - (또는) https://www.versioneye.com/python/setuptools/1.0
     1) 위의 사이트에서 다운로드
     2) cmd 창에서 다운 받은 폴더로 이동
     3) python ez_setup.py build 입력 후 python ez_setup.py 


4. 환경변수에 파이썬 script Path 추가

 (C:\Python27\Scripts)


5. Pip설치 
    1) cmd 창에서 3번에서 다운로드한 setuptool에 이동  
    2) easy_install pip 입력 (bestest 7.1.2) 


6. gdata 설치    

    1) cmd 창에서 3번에서 다운로드한 setuptool에 이동  
    2) 
easy_install gdata 입력 (latest 2.0.18)


7. AndroidStudio에 Python Community Edition Plugin 설치

   포스팅에서는 Python Community Edition Plugin 이 있다고 나오지만 제가 테스트할 때는 찾아볼 수 없었습니다.

   그대신 Python 이라는 것으로 있어서 이것으로 테스트하였습니다. (통합된 것을 예상됩니다.)



[포스팅에서 언급한 Python Community Edition]


[테스트한 Python Plugin]


8. 프로젝트에 파이썬 스크립트 복사

  아이디와 패스를 넣었더니 권한 없음 오류를 뿜어내서 소스를 수정하여 아이디와 password를 받지 않고  링크가 있는 읽기전용 파일을 받아오도록 하였습니다. 

경로는 [module name] - script가 Default 입니다만 소스를 수정하여 변경 할 수 있습니다.

포스트에서 언급한 경로로 이동하는 가장 쉬운 방법은 3단계로 구성됩니다.

1) app > 마우스 오른쪽 단추 > Show in Explorer
2) window 창 호출 되면 app 폴더 진입
3) script 폴더 생성

위의 방법으로 하면 script 폴더가 생성된 것을 확인할 수 있습니다. 이 폴더안에 아래의 파이썬 스크립트 복사해주세요.

  
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import csv;

import gdata.docs.service
import gdata.spreadsheet.service

from xml.etree.ElementTree import ElementTree, Element, SubElement, dump


'''
    get google doc information from the command line argument
    download method
    Create by : YoungChan Lee
    Modify by : KyuChan Shin
'''
def get_gdoc_information_android():
    #email = raw_input('Email address:')
    #password = getpass('Password:')
    #gdoc_id = raw_input('Google Doc Id:')
    gdoc_id = sys.argv[1]
    downloadpath = sys.argv[2]
    try:
        file_path = download(gdoc_id)
        readCSV(downloadpath,file_path)
    except Exception, e:
        print ":::::::::::::ERROR:::::::::::::"
        print(e)
        #raise e

def download(gdoc_id, download_path=None, ):

    print "Downloading the CVS file with id %s" % gdoc_id

    gd_client = gdata.docs.service.DocsService()


    #auth using ClientLogin
    gs_client = gdata.spreadsheet.service.SpreadsheetsService()
    #gs_client.ClientLogin(email, password)

    #getting the key(resource id and tab id from the ID)
    resource    = gdoc_id.split('#')[0]
    tab         = gdoc_id.split('#')[1].split('=')[1]
    resource_id = 'spreadsheet:'+resource

    if download_path is None:
        download_path = os.path.abspath(os.path.dirname(__file__))

    file_name = os.path.join(download_path, '%s.csv' % (gdoc_id))

    print 'download_path : %s' % download_path;
    print 'Downloading spreadsheet to %s' % file_name


    docs_token = gd_client.GetClientLoginToken()
    gd_client.SetClientLoginToken(gs_client.GetClientLoginToken())
    gd_client.Export(resource_id, file_name, gid=tab)
    gd_client.SetClientLoginToken(docs_token)

    print "Download Completed!"

    return file_name

def readCSV(savepath, file_name):
    print "read CSV file : %s" % file_name
    SourceCSV= open(file_name,"r")
    csvReader = csv.reader(SourceCSV)
    header = csvReader.next()
    androidkey_idx = header.index("android_key")
    eng_idx = header.index("eng")
    kor_idx = header.index("kor")

    # Make an empty Element
    resources_eng = Element("resources")
    resources_kor = Element("resources")

    # Loop through the lines in the file and get each coordinate
    for row in csvReader:
        androidkey = row[androidkey_idx]
        eng = row[eng_idx]

        kor = row[kor_idx]
        if not row[kor_idx]:
            kor = row[eng_idx]


        #append eng resource
        if row[eng_idx]:
            string_eng = Element("string")
            string_eng.attrib["name"] = androidkey.decode('utf-8')
            string_eng.text = eng.decode('utf-8')
            resources_eng.append(string_eng)

            #append kor resource
            string_kor = Element("string")
            string_kor.attrib["name"] = androidkey.decode('utf-8')
            string_kor.text =  kor.decode('utf-8')
            resources_kor.append(string_kor)



    # Print the coordinate list    
    #dump(resources_eng)
    #dump(resources_kor)

    #Make Resource Folder
    newpath_en = savepath+r'\values'
    if not os.path.exists(newpath_en):
        os.makedirs(newpath_en)

    newpath_ko = savepath+r'\values-ko'
    if not os.path.exists(newpath_ko):
        os.makedirs(newpath_ko)

    #make Xml file
    ElementTree(resources_eng).write(newpath_en+"\\string.xml", "utf-8")
    ElementTree(resources_kor).write(newpath_ko+"\\string.xml", "utf-8")

    SourceCSV.close()
    os.remove(file_name)


if __name__=='__main__':
    get_gdoc_information_android()


IOS 같은 경우는 포스트 한 곳에서 김로또님께서 재능기부해주셨습니다.


readCSV 쪽 함수만 수정해서 사용했다고 합니다.


https://slack-files.com/T02TMQL6T-F1JPBNSP3-986c3e480d


  
def readCSV(savepath, file_name):
    # print "read CSV file : %s" % file_name
    SourceCSV = open(file_name,"r")
    csvReader = csv.reader(SourceCSV)
    header = csvReader.next()

    languages = ["ko", "en"]
    indexes = [0, 0] 
    values = ["", ""]

    keyIndex = header.index("key")

    for i, language in enumerate(languages):
        indexes[i] = header.index(language)

    for row in csvReader:
        for i, language in enumerate(languages):
            key = '"' + row[keyIndex] + '"'
            value = '"' + row[indexes[i]] + '"'
            values[i] = values[i] + key + "=" + value + ";\n"

    for i, language in enumerate(languages):
        outputFile = savepath + "/" + language + ".lproj/Localizable.strings"

        try:
            outputStream = open(outputFile, "w")
            outputStream.write(values[i])
            outputStream.close()
        except :
            print "Error: " + language

    SourceCSV.close()
    os.remove(file_name)




9.구글 시트 만들기

    구글 닥스에서 스프레드 시트를 생성합니다.
    구글 시트는 메인개발자(관리자)와 번역가를 이메일로 초대하여 수정권한을 제한합니다.




시트 구조는 위와 같이  영어, 한국어, ios, android 구분하여서 등록합니다.


만약 더 많은 언어를 지원할 경우 eng, kor, 기타 나라, ios, android 순으로 설정하는게 
나중에 소스 편집하는데 더 편할 것으로 예상됩니다.


10.구글 스크립트 생성





function myFunction() {
  
}


function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "iOS Resource sheet",
    functionName : "iOSSheet"
  }, {
    name : "Android Resource sheet",
    functionName : "AndroidSheet"
  }];
  sheet.addMenu("리소스 만들기", entries);
};


function AndroidSheet(){
  var FileName = SpreadsheetApp.getActiveSpreadsheet().getName()+"_and";
  var files = DriveApp.getFilesByName(FileName);
  
  var sheet;
  // Check we found a sheet with the name
  while (files.hasNext()){
    sheet = files.next();
    if(sheet.getName() == FileName){
      Logger.log("Opened Sheet: " + FileName);
      return makeAndroidResource(sheet.getId());
    }
  }
  
  // We didn't find the file, so create it.
  sheet = SpreadsheetApp.create(FileName);
  Logger.log("Created new Sheet for: " + FileName);
  
  
  return makeAndroidResource(sheet.getId());
  
}

function iOSSheet(){
  var FileName = SpreadsheetApp.getActiveSpreadsheet().getName()+"_iOS";
  var files = DriveApp.getFilesByName(FileName);
  
  var sheet;
  // Check we found a sheet with the name
  while (files.hasNext()){
    sheet = files.next();
    if(sheet.getName() == FileName){
      Logger.log("Opened Sheet: " + FileName);
      return makeiOSResource(sheet.getId());
    }
  }
  
  // We didn't find the file, so create it.
  sheet = SpreadsheetApp.create(FileName);
  Logger.log("Created new Sheet for: " + FileName);
  
  
  return makeiOSResource(sheet.getId());
  
}

function makeAndroidResource(fileId){  
  // Get Spreadsheets
  var SourceSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  var Targetspreadsheet = SpreadsheetApp.openById(fileId); //새로운 파일
  // Set Sheets
  var SourceSheet = SourceSpreadSheet.getSheets()[0];
  var TargetSheet  = Targetspreadsheet.getSheets()[0];
  
  TargetSheet.clear();
  
  // Get Source last row
  var last_row = SourceSpreadSheet.getLastRow();

  // Set Ranges
  var source_range = SourceSpreadSheet.getRange("A1:C"+last_row);
  var target_range = Targetspreadsheet.getRange("A1:C"+last_row);
  // 안드로이드 키 값
  var source_key_range = SourceSpreadSheet.getRange("D1:D"+last_row);
  var target_key_range = Targetspreadsheet.getRange("C1:C"+last_row);
  
  // Fetch values
  var values = source_range.getValues();
  var key_values = source_key_range.getValues();
  
  // Save to spreadsheet
  target_range.setValues(values);
  target_key_range.setValues(key_values);
  
}

function makeiOSResource(fileId){  
  // Get Spreadsheets
  var SourceSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  var Targetspreadsheet = SpreadsheetApp.openById(fileId); //새로운 파일
  // Set Sheets
  var SourceSheet = SourceSpreadSheet.getSheets()[0];
  var TargetSheet  = Targetspreadsheet.getSheets()[0];
  
  TargetSheet.clear();
  
  // Get Source last row
  var last_row = SourceSpreadSheet.getLastRow();

  // Set Ranges
  var source_range = SourceSpreadSheet.getRange("A1:C"+last_row);
  var target_range = Targetspreadsheet.getRange("A1:C"+last_row);
  // ios 키 값
  var source_key_range = SourceSpreadSheet.getRange("C1:C"+last_row);
  var target_key_range = Targetspreadsheet.getRange("C1:C"+last_row);
  
  // Fetch values
  var values = source_range.getValues();
  var key_values = source_key_range.getValues();
  
  //ignore header
  for(var i=1; i< values.length; i++){
    values[i][0] = "\""+key_values[i]+"\"=\""+ values[i][0] +"\";";
    values[i][1] = "\""+key_values[i]+"\"=\""+ values[i][1] +"\";";
    values[i][2] = "\""+key_values[i]+"\"=\""+ values[i][2] +"\";";        
  }
  
  
  // Save to spreadsheet 
  target_range.setValues(values);
  //target_key_range.setValues(key_values);
  
}


위의 내용을 리소스 편집기에 넣어둡니다.


시트로 돌아가면 "리소스 만들기" 메뉴가 생성되어 있습니다.


이 새로 생성된 메뉴를 이용하여 안드로이드, ios 용 시트를 생성합니다.


생성된 시트로 이동하여서 공유하기를 누릅니다.


인터넷의 모든 사용자가 찾고 볼 수 있음을 클릭합니다.


이 부분이 가장 중요합니다. 전 이 권한을 잘못 설정해서 몇 시간 고생했습니다 ㅠ




11. build.gradle 수정하기

    build.gradle에 파이선 스크립트를 실행하는 task를 추가합니다.

  
ext.download_res_folder = 'src/main/res_down' //저장될 별도의 리소스 폴더
ext.script_path = 'script/languageResource.py' //스크립트 저장 경로
ext.GoogleDocId = 'Google Doc ID'
 
task StringResourceSync(type: Exec) {
    doFirst {
        println ":::" + "Start to get String Resources..." + ":::"
    }
    commandLine = ['cmd', '/c', 'python' , script_path, GoogleDocId,download_res_folder]
    //mac
    //commandLine =['python', script_path, GoogleDocId,download_res_folder]
    doLast {
        println ":::" + "Finish to get String Resources..." + ":::"
    }
}
 
preBuild.dependsOn StringResourceSync
 
android {
    ...
    sourceSets {
        main.res.srcDirs += download_res_folder
    }
    ...
}

12.gradle sync

    프로젝트를 빌드하거나 gradle 프로젝트를 project sync 하게 되면 언어 리소스를 다운받아 새로운 언어 리소스를 생성합니다.

자세한 설명과 소스는 http://tiii.tistory.com/22 을 참고해주세요.


정리

파이션을 모르고 접근했기에 무작정 돌려봤는데 파이션의 매력에 조금 빠졌네요.

파이션을 응용해서 gradle을 사용하면 더 다양한 안드로이드 빌드가 가능 할 것으로 보입니다.


참고

http://tiii.tistory.com/22
https://www.versioneye.com/python/setuptools/1.0

반응형
댓글