Извлечение файлов перевода из OneSky и публикация их на AWS S3 с Gulp.js - PullRequest
0 голосов
/ 23 мая 2018

Я пишу сценарий Gulp, чтобы отправить некоторые файлы JSON на мой S3.(Я загружаю файлы перевода из OneSky и помещаю их в S3).

Я использую пакет gulp-require-tasks, чтобы разделить свои задачи на подфайлы, поэтому мой файл задач выглядит следующим образом:

const env = require('gulp-env')
const glob = require('glob')
const fs = require('fs')
const onesky = require('onesky-utils')
const path = require('path')
const AWS = require('aws-sdk/dist/aws-sdk-react-native')

TRANSLATION_LANGUAGES = ['fr-BE']

// ~~~~ Task ~~~~
module.exports = function() {
  env({ file: '.gulp-env.json' })

  for(var locale of TRANSLATION_LANGUAGES) {
    glob('./locales/' + process.env.ONESKY_BASE_LOCALE + '/*.json', {}, function (er, files) {
      files.forEach(function(file) {
        pullOneSkyFile(file, locale).then(content => {
          // Replace the root key with the current locale
          content = content.replace(process.env.ONESKY_BASE_LOCALE, locale)
          const translationFile = writeFile(file, locale, content)
          pushToAmazonS3(translationFile, locale, content)
        }).catch(error => {
          if (error.message === 'Invalid source file') {
            throw Error('The file', file, 'is not present on OneSky')
          } else {
            console.error('ERROR:', error)
          }
        })
      })
    })
  }
}

// ~~~~ Helper Methods ~~~~
function writeFile(file, locale, content) {
  const languageFolder = './locales/' + locale
  if (!fs.existsSync(languageFolder)) {
    console.log('Creating the folder', languageFolder)
    fs.mkdirSync(languageFolder);
  }

  const filePath = languageFolder + '/' + path.basename(file)
  fs.writeFileSync(filePath, content, 'utf-8');
  console.log('File', filePath, 'successfully updated localy for locale', locale, '.')
  return filePath
}

function pushToAmazonS3(filePath, locale, content) {
  console.log('Pushing the file', path.basename(filePath), 'with locale', locale, 'to Amazon S3...')

  const file = {
    // `uri` can also be a file system path (i.e. file://)
    uri: 'file://' + path.resolve(filePath),
    name: path.basename(filePath),
    type: 'application/json'
  }

  console.log('file', file)

  AWS.config.update({
    region: process.env.AMAZON_S3_REGION,
    accessKeyId: process.env.AMAZON_S3_ACCESS_KEY_ID,
    secretAccessKey: process.env.AMAZON_S3_SECRET_ACCESS_KEY
  })

  var s3 = new AWS.S3();
  s3.putObject({Bucket: 'companion-assets', Key: 'test', Body: content}, function (err) {
    if (err) {
      throw err
    } else {
      console.log('Uploading asset', file)
      fileStream.close()
    }
  })
}

function pullOneSkyFile(file, locale) {
  console.log('Pulling the file', path.basename(file), 'with locale', locale, '...')

  return onesky.getFile({
    apiKey: process.env.ONESKY_API_KEY,
    secret: process.env.ONESKY_SECRET_KEY,
    projectId: process.env.ONESKY_PROJECT_ID,
    language: locale,
    fileName: path.basename(file)
  })
}

Когда я выполняю эту задачу, я получаю следующий вывод:

[15:55:07] Using gulpfile ~/Developments/companion/gulpfile.js
[15:55:07] Starting 'onesky-pull-aws-s3-push'...
locale fr-BE
Pulling the file screens.login.json with locale fr-BE ...
File ./locales/fr-BE/screens.login.json successfully updated localy for locale fr-BE .
Pushing the file screens.login.json with locale fr-BE to Amazon S3...
file { uri: 'file:///Users/zedtux/Developments/companion/locales/fr-BE/screens.login.json',
  name: 'screens.login.json',
  type: 'application/json' }
/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:7090
                    throw err;
                    ^

NetworkingError: XMLHttpRequest is not defined
    at features.constructor.handleRequest (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:31583:16)
    at executeSend (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:6147:31)
    at Request.SEND (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:6161:11)
    at Request.callListeners (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:5704:20)
    at Request.emit (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:5680:12)
    at Request.emit (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:7742:16)
    at Request.transition (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:7081:12)
    at AcceptorStateMachine.runTo (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:7885:14)
    at /Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:7897:12
    at Request.<anonymous> (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:7097:11)
    at Request.<anonymous> (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:7744:14)
    at Request.callListeners (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:5718:20)
    at callNextListener (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:5698:14)
    at /Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:6063:11
    at finish (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:4746:9)
    at /Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:4764:11
    at Credentials.get (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:15525:8)
    at getAsyncCredentials (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:4758:26)
    at Config.getCredentials (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:4778:11)
    at Request.SIGN (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:6035:24)
    at Request.callListeners (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:5704:20)
    at Request.emit (/Users/zedtux/Developments/companion/node_modules/aws-sdk/dist/aws-sdk-react-native.js:5680:12)

Я понимаю, что проблема в том, что библиотека AWS создана для запуска в веб-браузере или вродное приложение React, но в этом случае я просто пишу скрипт «glup».

Как я могу решить эту проблему?

1 Ответ

0 голосов
/ 24 мая 2018

Я на самом деле полностью переписал все, способ Glup, и теперь он работает просто отлично!

Я больше не использую gulp-require-tasks и вот мой код.

gulpfile.js:

const awspublish = require('gulp-awspublish')
const env = require('gulp-env')
const gulp = require('gulp')
const oneSkyPull = require('./gulp-plugins/onesky-pull')
const rename = require('gulp-rename')

/*
** Pull translations from OneSky to the locale disk, then upload them to an
*  Amazon S3 bucket.
*/
gulp.task('i18n-deploy', function() {
  env({ file: '.gulp-env.json' }) // Load environment variables

  // Prepare the AWS S3 object
  var publisher = awspublish.create({
    accessKeyId: process.env.AMAZON_S3_ACCESS_KEY_ID,
    secretAccessKey: process.env.AMAZON_S3_SECRET_ACCESS_KEY,
    region: process.env.AMAZON_S3_REGION,
    params: {
      Bucket: 'companion-assets'
    }
  }, {
    cacheFileName: 'aws-s3-cache'
  })

  // Walk through all the base language translation files
  // The { base: 'companion' } here is used in order to keep the folder
  // strucutre on S3, otherwise the files were uploaded at the root of
  // the S3 bucket.
  gulp.src('./locales/' + process.env.ONESKY_BASE_LOCALE + '/*.json', { base: 'companion' })
      .pipe(oneSkyPull({
        baseLocale: process.env.ONESKY_BASE_LOCALE,
        locales: ['fr-BE'], // All translation languages
        oneskyApiKey: process.env.ONESKY_API_KEY,
        oneskySecretKey: process.env.ONESKY_SECRET_KEY,
        oneskyProjectId: process.env.ONESKY_PROJECT_ID
      })) // Fetch translation files from OneSky
      .pipe(rename(function(path) {
        // Remove the `../` part from the absolute path avoiding AWS error
        path.dirname = path.dirname.replace('../', '')
      }))
      .pipe(publisher.publish()) // Push to Amazon S3
})

А вот мой файл плагина для OneSky:

const fs = require('fs')
const gutil = require('gulp-util')
const onesky = require('onesky-utils')
const path = require('path')
const through = require('through2')

const PLUGIN_NAME = 'onesky-pull'

// OneSky function to pull the translation file for the given locale
// and given file.
function oneSkyPullFile(file, locale, options) {
  console.log('Pulling the file', path.basename(file), 'with locale', locale, '...')

  return onesky.getFile({
    apiKey: options.oneskyApiKey,
    secret: options.oneskySecretKey,
    projectId: options.oneskyProjectId,
    language: locale,
    fileName: path.basename(file)
  })
}

// Write the translation files on the disk, creating the folders if needed.
// Returns a gutil.File to be pushed in the stream.
function writeFile(file, baseLocale, locale, content) {
  var languageFolder = path.dirname(file)
  languageFolder = languageFolder.replace(baseLocale, locale)
  if (!fs.existsSync(languageFolder)) {
    console.log('Creating the folder', languageFolder)
    fs.mkdirSync(languageFolder);
  }

  const filePath = languageFolder + '/' + path.basename(file)
  fs.writeFileSync(filePath, content, 'utf-8');
  console.log('File', filePath, 'successfully updated localy for locale', locale, '.')
  return new gutil.File({
    path: filePath,
    contents: new Buffer.from(content)
  })
}

// Plugin main functiomn
module.exports = function(options) {
  options = options || {}

  if (!options.baseLocale)
    throw new gutil.PluginError(PLUGIN_NAME, 'please specify the base locale (baseLocale)')

  if (!options.locales)
    throw new gutil.PluginError(PLUGIN_NAME, 'please specify the locales (locales)')

  if (!options.oneskyApiKey)
    throw new gutil.PluginError(PLUGIN_NAME, 'please specify your OneSky API Key (oneskyApiKey)')

  if (!options.oneskySecretKey)
    throw new gutil.PluginError(PLUGIN_NAME, 'please specify your OneSky Secret Key (oneskySecretKey)')

  if (!options.oneskyProjectId)
    throw new gutil.PluginError(PLUGIN_NAME, 'please specify your OneSky Project ID (oneskyProjectId)')

  return through.obj(function (file, encoding, callback) {
    if (file.isNull()) {
      this.push(file) // Do nothing if no contents
      return callback()
    }

    if (file.isBuffer()) {
      for(var locale of options.locales) {
        oneSkyPullFile(file.path, locale, options).then(content => {
          // OneSky build a JSON file based on the base language file with
          // the target locale translations.
          // So we replace the base locale with the current one.
          content = content.replace(options.baseLocale, locale)
          // Write the file on the disk
          const translationFile = writeFile(file.path, options.baseLocale, locale, content)
          // Add back the vynil file to the stream
          this.push(file)
          // Add the created translation file to the stream (so that it will be
          // available for the next plugins).
          this.push(translationFile)

          return callback()
        }).catch(error => {
          if (error.message === 'Invalid source file') {
            this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'The file', file, 'is not present on OneSky'))
          } else {
            this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'ERROR:' + error))
          }
          return callback()
        })
      }
    }

    if (file.isStream()) {
      this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'ERROR: Streams are not supported'))
      return callback()
    }
  })
}

При запуске задачи выдается следующий вывод:

[12:15:45] Using gulpfile ~/Developments/companion/gulpfile.js
[12:15:45] Starting 'i18n-deploy'...
[12:15:45] Finished 'i18n-deploy' after 11 ms
Pulling the file screens.login.json with locale fr-BE ...
file /Users/zedtux/Developments/companion/locales/fr-FR/screens.login.json
path.dirname(file) /Users/zedtux/Developments/companion/locales/fr-FR
File /Users/zedtux/Developments/companion/locales/fr-BE/screens.login.json successfully updated localy for locale fr-BE .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...