Class: PhraseAppUpdater::PhraseAppAPI

Inherits:
Object
  • Object
show all
Defined in:
lib/phraseapp_updater/phraseapp_api.rb

Defined Under Namespace

Classes: BadAPIKeyError, BadProjectIDError, Locale, MissingGitParentError, ProjectNameTakenError, ProjectNotFoundError

Constant Summary collapse

GIT_TAG_PREFIX =
'gitancestor_'
PAGE_SIZE =
100

Instance Method Summary collapse

Constructor Details

#initialize(api_key, project_id, locale_file_class) ⇒ PhraseAppAPI

Returns a new instance of PhraseAppAPI.



15
16
17
18
19
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 15

def initialize(api_key, project_id, locale_file_class)
  @client            = PhraseApp::Client.new(PhraseApp::Auth::Credentials.new(token: api_key))
  @project_id        = project_id
  @locale_file_class = locale_file_class
end

Instance Method Details

#create_locale(name, default: false) ⇒ Object



68
69
70
71
72
73
74
75
76
77
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 68

def create_locale(name, default: false)
  phraseapp_request do
    params = PhraseApp::RequestParams::LocaleParams.new(
      name: name,
      code: name,
      default: default,
    )
    @client.locale_create(@project_id, params)
  end
end

#create_project(name, parent_commit) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 21

def create_project(name, parent_commit)
  params = PhraseApp::RequestParams::ProjectParams.new(
    name: name,
    main_format: @locale_file_class.phraseapp_type)
  project = phraseapp_request { @client.project_create(params) }
  STDERR.puts "Created project #{name} for #{parent_commit}"

  @project_id = project.id
  store_parent_commit(parent_commit)

  project.id
end

#download_file(locale, skip_unverified) ⇒ Object



111
112
113
114
115
116
117
118
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 111

def download_file(locale, skip_unverified)
  download_params = PhraseApp::RequestParams::LocaleDownloadParams.new

  download_params.file_format                  = @locale_file_class.phraseapp_type
  download_params.skip_unverified_translations = skip_unverified

  phraseapp_request { @client.locale_download(@project_id, locale.id, download_params) }
end

#download_files(locales, skip_unverified:) ⇒ Object



79
80
81
82
83
84
85
86
87
88
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 79

def download_files(locales, skip_unverified:)
  results = threaded_request(locales) do |locale|
    STDERR.puts "Downloading file for #{locale}"
    download_file(locale, skip_unverified)
  end

  locales.zip(results).map do |locale, file_contents|
    @locale_file_class.from_file_content(locale.name, file_contents)
  end
end

#fetch_localesObject



60
61
62
63
64
65
66
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 60

def fetch_locales
  # This is a paginated API, however the maximum page size of 100 is well
  # above our expected locale size, so we take the first page only for now
  phraseapp_request { @client.locales_list(@project_id, 1, 100) }.map do |pa_locale|
    Locale.new(pa_locale)
  end
end

#lookup_project_id(name) ⇒ Object



34
35
36
37
38
39
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 34

def lookup_project_id(name)
  result, = paginate_request(:projects_list, limit: 1) { |p| p.name == name }
  raise ProjectNotFoundError.new(name) if result.nil?

  result.id
end

#read_parent_commitObject

We mark projects with their parent git commit using a tag with a well-known prefix. We only allow one tag with this prefix at once.



43
44
45
46
47
48
49
50
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 43

def read_parent_commit
  git_tag, = paginate_request(:tags_list, @project_id, limit: 1) do |t|
    t.name.start_with?(GIT_TAG_PREFIX)
  end
  raise MissingGitParentError.new if git_tag.nil?

  git_tag.name.delete_prefix(GIT_TAG_PREFIX)
end

#remove_keys_not_in_upload(upload_id) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 134

def remove_keys_not_in_upload(upload_id)
  delete_params   = PhraseApp::RequestParams::KeysDeleteParams.new
  delete_params.q = "unmentioned_in_upload:#{upload_id}"

  begin
    phraseapp_request { @client.keys_delete(@project_id, delete_params) }
  rescue RuntimeError => _e
    # PhraseApp will accept but mark invalid uploads, however the gem
    # returns the same response in both cases. If we call this API
    # with the ID of an upload of a bad file, it will fail.
    # This usually occurs when sending up an empty file, which is
    # a case we can ignore. However, it'd be better to have a way
    # to detect a bad upload and find the cause.
  end
end

#remove_keys_not_in_uploads(upload_ids) ⇒ Object



104
105
106
107
108
109
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 104

def remove_keys_not_in_uploads(upload_ids)
  threaded_request(upload_ids) do |upload_id|
    STDERR.puts "Removing keys not in upload #{upload_id}"
    remove_keys_not_in_upload(upload_id)
  end
end

#update_parent_commit(commit_hash) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 52

def update_parent_commit(commit_hash)
  previous_parent = read_parent_commit
  phraseapp_request do
    @client.tag_delete(@project_id, GIT_TAG_PREFIX + previous_parent)
  end
  store_parent_commit(commit_hash)
end

#upload_file(locale_file) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 120

def upload_file(locale_file)
  upload_params = create_upload_params(locale_file.locale_name)

  # The PhraseApp gem only accepts a filename to upload,
  # so we need to write the file out and pass it the path
  Tempfile.create([locale_file.locale_name, ".json"]) do |f|
    f.write(locale_file.content)
    f.close

    upload_params.file = f.path
    phraseapp_request { @client.upload_create(@project_id, upload_params) }.id
  end
end

#upload_files(locale_files, default_locale:) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/phraseapp_updater/phraseapp_api.rb', line 90

def upload_files(locale_files, default_locale:)
  known_locales = fetch_locales.index_by(&:name)

  threaded_request(locale_files) do |locale_file|
    unless known_locales.has_key?(locale_file.locale_name)
      create_locale(locale_file.locale_name,
                    default: (locale_file.locale_name == default_locale))
    end

    STDERR.puts "Uploading #{locale_file}"
    upload_file(locale_file)
  end
end