1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
# -*- coding: utf-8 -*-
=begin rdoc
Transifexと連携するためのユーティリティ
=end
module Transifex
extend self
API_URL_PREFIX = 'https://www.transifex.com/api/2'.freeze
SLUG_SIZE = 50
CONTENT_TYPE_MULTIPART_FORMDATA = 'multipart/form-data'
CONTENT_TYPE_APPLICATION_JSON = 'application/json'
# Transifexプロジェクトの情報を取得する
# ==== Args
# [project_name] String プロジェクト名
# ==== Return
# Hashプロジェクトの情報
def project_detail(project_name)
get_request("/project/#{project_name}/?details")
end
# resource(mikutterの場合はpotファイル)をアップロードし、新しいResourceとして登録する。
# 既に同じslugを持つResourceは登録できない。代わりに、 Transifex.resource_update を使う
# ==== Args
# [project_name:] プロジェクト名
# [slug:] String アップロードするresourceのslug。プラグインスラッグを使用する。50文字まで
# [name:] String resourceの名前。プラグイン名を使用する。
# [i18n_type:] String 翻訳形式。省略するとPO。mikutterでは必ず省略する。
# [categories:] Array カテゴリ。いらん
# [priority:] Transifex::Priority 翻訳優先順位。
# [content:] IO|String resourceの内容。potファイルの中身のこと。IOを渡すとそれをreadした結果、Stringならその内容をそのままアップロードする
# ==== Return
# Hash レスポンス
# ==== See
# http://docs.transifex.com/api/resources/#uploading-and-downloading-resources
# ==== Raise
# SlugTooLongError slugが SLUG_SIZE 文字を超えている場合
def resource_create(project_name:, slug:, name:, i18n_type: 'PO', categories: [], priority: Priority::NORMAL, content:)
slug, name, priority = slug.to_s, name.to_s, priority.to_i
raise SlugTooLongError, "The current maximum value for the field slug is #{SLUG_SIZE} characters. http://docs.transifex.com/api/resources/#uploading-and-downloading-resources" if slug.size > SLUG_SIZE
if content.is_a? IO
content = content.read end
post_request("/project/#{project_name}/resources/",
content_type: CONTENT_TYPE_APPLICATION_JSON,
params: {
slug: slug,
name: name,
i18n_type: i18n_type,
categories: categories,
priority: priority,
content: content
}
)
end
# resource(mikutterの場合はpotファイル)をアップロードし、同じslugを持つResourceを上書きする。
# 存在しないResourceは登録できない。代わりに、 Transifex.resource_create を使う
# ==== Args
# [project_name:] プロジェクト名
# [slug:] String アップロードするresourceのslug。プラグインスラッグを使用する。50文字まで
# [content:] IO|String resourceの内容。potファイルの中身のこと。IOを渡すとそれをreadした結果、Stringならその内容をそのままアップロードする
# ==== Return
# Hash レスポンス
# ==== See
# http://docs.transifex.com/api/resources/#uploading-and-downloading-translations-for-a-file
def resource_update(project_name:, slug:, content:)
slug = slug.to_s
if content.is_a? IO
content = content.read end
put_request("/project/#{project_name}/resource/#{slug}/content/",
content_type: CONTENT_TYPE_APPLICATION_JSON,
params: {content: content}
)
end
def resource_get(project_name:, slug:)
slug = slug.to_s
get_request("/project/#{project_name}/resource/#{slug}/content/")
end
private
def get_request(path)
clnt = HTTPClient.new
clnt.set_auth(API_URL_PREFIX, ENV['TRANSIFEX_USER'], ENV['TRANSIFEX_PASSWORD'])
JSON.parse(clnt.get_content(API_URL_PREFIX + path), symbolize_names: true)
end
def post_request(path, content_type: CONTENT_TYPE_MULTIPART_FORMDATA, params:)
clnt = HTTPClient.new
clnt.set_auth(API_URL_PREFIX, ENV['TRANSIFEX_USER'], ENV['TRANSIFEX_PASSWORD'])
case content_type
when CONTENT_TYPE_MULTIPART_FORMDATA
content = params
when CONTENT_TYPE_APPLICATION_JSON
content = params.to_json
end
JSON.parse(clnt.post_content(API_URL_PREFIX + path, content, 'Content-Type' => content_type), symbolize_names: true)
rescue HTTPClient::BadResponseError => err
pp err.res.content
end
def put_request(path, content_type: CONTENT_TYPE_MULTIPART_FORMDATA, params:)
clnt = HTTPClient.new
clnt.set_auth(API_URL_PREFIX, ENV['TRANSIFEX_USER'], ENV['TRANSIFEX_PASSWORD'])
case content_type
when CONTENT_TYPE_MULTIPART_FORMDATA
content = params
when CONTENT_TYPE_APPLICATION_JSON
content = params.to_json
end
JSON.parse(clnt.__send__(:follow_redirect, :put, API_URL_PREFIX + path, nil, content, 'Content-Type' => content_type).content, symbolize_names: true)
rescue HTTPClient::BadResponseError => err
pp err.res.content
end
class Priority
attr_reader :to_i
def initialize(prio)
@to_i = prio.to_i end
NORMAL = new(0)
HIGH = new(1)
URGENT = new(2)
end
class Error < RuntimeError; end
class SlugTooLongError < Error; end
end
|