lara-sdk 1.6.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a3b69ad7aedd5fba6abf61cd338174f91c6784780afb48ed888f2d6781c225f
4
- data.tar.gz: 8f736b1507a97c1da997e8136bf6407de5e3a687c704573397284ea093c4fa2b
3
+ metadata.gz: 40c690defef56e7663867a644181be99f0a6cc6576abc9b4d7f79e57193c3853
4
+ data.tar.gz: 6d847c2b8b5caeaef7a45ec6624906a9b26ba29ff3105ea76e2eab7eb4d84adf
5
5
  SHA512:
6
- metadata.gz: ed938c0f7ddd966f7307cb13c33500931d2e5f87d10cdd4590b999b37b660148b95a7d5e73a73b0d69eafc464eb98a1c8a03e3b533cfd362f8e434aca995db96
7
- data.tar.gz: c3b778924d5b7e09ddf9efff21aed919579cf86df566ada5f96a044c043f6bf3e3fc529ee81c2c7f34c84d576f7f628b07a08719fcf1eadbef3dc7becf34e9c5
6
+ metadata.gz: ec70756013dfda0e007d16fcc2c165836b737017c1a8ad198cfe9d4763694c2a251d069ed9a177d3683b636fdae997a40559a1d6743c8c632387cfa5c628e3bf
7
+ data.tar.gz: e8672051a95c85a847d66560c5ccbbb16dcbaf2b2d1060f5468d4b609b30cb007b8e1c823c96df2f01259b16da4cd50e5c6272823dec68ba0f90ef00669e608e
data/lib/lara/client.rb CHANGED
@@ -218,7 +218,7 @@ module Lara
218
218
  return response.body if raw_response
219
219
 
220
220
  content_type = response.headers["content-type"] || response.headers["Content-Type"]
221
- return response.body if content_type&.include?("text/csv")
221
+ return response.body if content_type&.include?("text/csv") || content_type&.include?("application/xml")
222
222
 
223
223
  if callback || (body && body[:reasoning])
224
224
  parse_stream_response(response.body, &callback)
@@ -6,10 +6,11 @@ module Lara
6
6
  module FileFormat
7
7
  UNIDIRECTIONAL = "csv/table-uni"
8
8
  MULTIDIRECTIONAL = "csv/table-multi"
9
+ TBX = "tbx"
9
10
 
10
11
  # @return [Array<String>] All supported formats
11
12
  def self.all
12
- [UNIDIRECTIONAL, MULTIDIRECTIONAL]
13
+ [UNIDIRECTIONAL, MULTIDIRECTIONAL, TBX]
13
14
  end
14
15
 
15
16
  # @param format [String] The format to validate
@@ -57,38 +58,62 @@ module Lara
57
58
  body: { name: name }).transform_keys(&:to_sym))
58
59
  end
59
60
 
61
+ # @return [Lara::Models::GlossaryShares]
62
+ def get_shares(id)
63
+ Lara::Models::GlossaryShares.new(**@client.get("/v2/glossaries/#{id}/shares").transform_keys(&:to_sym))
64
+ end
65
+
66
+ def add_account_share(id, name: nil)
67
+ glossary_from(@client.post("/v2/glossaries/#{id}/shares", body: { name: name }.compact))
68
+ end
69
+
70
+ def rename_account_share(id, name:)
71
+ glossary_from(@client.put("/v2/glossaries/#{id}/shares", body: { name: name }))
72
+ end
73
+
74
+ def revoke_account_share(id)
75
+ glossary_from(@client.delete("/v2/glossaries/#{id}/shares"))
76
+ end
77
+
78
+ def add_group_share(id, group_id, name: nil)
79
+ glossary_from(@client.post("/v2/glossaries/#{id}/shares/groups/#{group_id}", body: { name: name }.compact))
80
+ end
81
+
82
+ def rename_group_share(id, group_id, name:)
83
+ glossary_from(@client.put("/v2/glossaries/#{id}/shares/groups/#{group_id}", body: { name: name }))
84
+ end
85
+
86
+ def revoke_group_share(id, group_id)
87
+ glossary_from(@client.delete("/v2/glossaries/#{id}/shares/groups/#{group_id}"))
88
+ end
89
+
60
90
  # @return [Lara::Models::GlossaryCounts]
61
91
  def counts(id)
62
92
  Lara::Models::GlossaryCounts.new(**@client.get("/v2/glossaries/#{id}/counts").transform_keys(&:to_sym))
63
93
  end
64
94
 
65
- # @param content_type [String] Either FileFormat::UNIDIRECTIONAL or FileFormat::MULTIDIRECTIONAL
66
- # @param gzip [Boolean] When true, compress the CSV before upload and set compression=gzip
95
+ # Import options are independent keyword arguments; omitted options use their defaults.
96
+ # @param content_type [String] One of FileFormat.all; defaults to UNIDIRECTIONAL
97
+ # @param gzip [Boolean] Whether the supplied file is already gzip-compressed; defaults to false
67
98
  # @param callback_url [String,nil] Optional URL notified when the import completes
68
99
  # @return [Lara::Models::GlossaryImport]
69
- def import_csv(id, csv_path, content_type: FileFormat::UNIDIRECTIONAL, gzip: false,
70
- callback_url: nil)
100
+ def import_file(id, file_path, content_type: FileFormat::UNIDIRECTIONAL, gzip: false,
101
+ callback_url: nil)
71
102
  unless FileFormat.valid?(content_type)
72
103
  raise ArgumentError, "Invalid content_type. Supported formats: #{FileFormat.all.join(', ')}"
73
104
  end
74
105
 
75
- basename = File.basename(csv_path)
76
- if gzip
77
- require "stringio"
78
- require "zlib"
79
-
80
- buffer = StringIO.new
81
- gz = Zlib::GzipWriter.new(buffer, 7, Zlib::DEFAULT_STRATEGY)
82
- File.open(csv_path, "rb") { |_f| IO.copy_stream(_f, gz) }
83
- gz.finish
84
- buffer.rewind
85
-
86
- body = { "compression" => "gzip" }
87
- files = { "csv" => Faraday::UploadIO.new(buffer, "application/gzip", "#{basename}.gz") }
88
- else
89
- body = {}
90
- files = { "csv" => Faraday::UploadIO.new(csv_path, "text/csv", basename) }
91
- end
106
+ basename = File.basename(file_path)
107
+ mime_type = if gzip
108
+ "application/gzip"
109
+ elsif content_type == FileFormat::TBX
110
+ "application/xml"
111
+ else
112
+ "text/csv"
113
+ end
114
+ files = { "csv" => Faraday::UploadIO.new(file_path, mime_type, basename) }
115
+ body = {}
116
+ body["compression"] = "gzip" if gzip
92
117
 
93
118
  body["content_type"] = content_type unless content_type == FileFormat::UNIDIRECTIONAL
94
119
  body["callback_url"] = callback_url if callback_url
@@ -96,6 +121,16 @@ module Lara
96
121
  body: body, files: files).transform_keys(&:to_sym))
97
122
  end
98
123
 
124
+ # @deprecated Use #import_file instead.
125
+ def import_csv(id, csv_path, content_type: FileFormat::UNIDIRECTIONAL, gzip: false,
126
+ callback_url: nil)
127
+ warn "[DEPRECATION] import_csv is deprecated; use import_file instead.", uplevel: 1
128
+ unless [FileFormat::UNIDIRECTIONAL, FileFormat::MULTIDIRECTIONAL].include?(content_type)
129
+ raise ArgumentError, "import_csv only supports CSV formats; use import_file for TBX files."
130
+ end
131
+ import_file(id, csv_path, content_type: content_type, gzip: gzip, callback_url: callback_url)
132
+ end
133
+
99
134
  # @return [Lara::Models::GlossaryImport]
100
135
  def get_import_status(import_id)
101
136
  Lara::Models::GlossaryImport.new(**@client.get("/v2/glossaries/imports/#{import_id}").transform_keys(&:to_sym))
@@ -117,10 +152,10 @@ module Lara
117
152
  current
118
153
  end
119
154
 
120
- # Exports a csv file with the glossary content.
121
- # @param content_type [String] Either FileFormat::UNIDIRECTIONAL or FileFormat::MULTIDIRECTIONAL
122
- # @param source [String, nil] Optional source language
123
- # @return [String] bytes
155
+ # Exports the glossary in the requested format.
156
+ # @param content_type [String] One of the formats returned by FileFormat.all
157
+ # @param source [String, nil] Required for unidirectional CSV; omit for multidirectional CSV and TBX
158
+ # @return [String] Raw CSV or TBX content
124
159
  def export(id, content_type: FileFormat::UNIDIRECTIONAL, source: nil)
125
160
  unless FileFormat.valid?(content_type)
126
161
  raise ArgumentError, "Invalid content_type. Supported formats: #{FileFormat.all.join(', ')}"
@@ -131,8 +166,8 @@ module Lara
131
166
  end
132
167
 
133
168
  # @param callback_url [String] URL notified when the export is ready
134
- # @param content_type [String] Either FileFormat::UNIDIRECTIONAL or FileFormat::MULTIDIRECTIONAL
135
- # @param source [String, nil] Optional source language (unidirectional exports only)
169
+ # @param content_type [String] One of the formats returned by FileFormat.all
170
+ # @param source [String, nil] Required for unidirectional CSV; omit for multidirectional CSV and TBX
136
171
  # @return [Lara::Models::GlossaryExport]
137
172
  def export_async(id, callback_url:, content_type: FileFormat::UNIDIRECTIONAL, source: nil)
138
173
  unless FileFormat.valid?(content_type)
@@ -169,5 +204,11 @@ module Lara
169
204
  Lara::Models::GlossaryImport.new(**@client.delete("/v2/glossaries/#{glossary_id}/content",
170
205
  body: body).transform_keys(&:to_sym))
171
206
  end
207
+
208
+ private
209
+
210
+ def glossary_from(response)
211
+ Lara::Models::Glossary.new(**response.transform_keys(&:to_sym))
212
+ end
172
213
  end
173
214
  end
data/lib/lara/memories.rb CHANGED
@@ -69,6 +69,35 @@ module Lara
69
69
  models.first
70
70
  end
71
71
 
72
+ # @return [Lara::Models::MemoryShares]
73
+ def get_shares(id)
74
+ Lara::Models::MemoryShares.new(**@client.get("/v2/memories/#{id}/shares").transform_keys(&:to_sym))
75
+ end
76
+
77
+ def add_account_share(id, name: nil)
78
+ memory_from(@client.post("/v2/memories/#{id}/shares", body: { name: name }.compact))
79
+ end
80
+
81
+ def rename_account_share(id, name:)
82
+ memory_from(@client.put("/v2/memories/#{id}/shares", body: { name: name }))
83
+ end
84
+
85
+ def revoke_account_share(id)
86
+ memory_from(@client.delete("/v2/memories/#{id}/shares"))
87
+ end
88
+
89
+ def add_group_share(id, group_id, name: nil)
90
+ memory_from(@client.post("/v2/memories/#{id}/shares/groups/#{group_id}", body: { name: name }.compact))
91
+ end
92
+
93
+ def rename_group_share(id, group_id, name:)
94
+ memory_from(@client.put("/v2/memories/#{id}/shares/groups/#{group_id}", body: { name: name }))
95
+ end
96
+
97
+ def revoke_group_share(id, group_id)
98
+ memory_from(@client.delete("/v2/memories/#{id}/shares/groups/#{group_id}"))
99
+ end
100
+
72
101
  # @return [Lara::Models::MemoryImport]
73
102
  def add_translation(id_or_ids, source:, target:, sentence:, translation:, tuid: nil,
74
103
  sentence_before: nil, sentence_after: nil, headers: nil)
@@ -115,20 +144,14 @@ module Lara
115
144
  end
116
145
  end
117
146
 
147
+ # @param gzip [Boolean] Whether the supplied file is already gzip-compressed; defaults to false
118
148
  # @return [Lara::Models::MemoryImport]
119
- def import_tmx(id, tmx_path, callback_url: nil)
120
- require "stringio"
121
- require "zlib"
149
+ def import_tmx(id, tmx_path, gzip: false, callback_url: nil)
122
150
  basename = File.basename(tmx_path)
123
-
124
- buffer = StringIO.new
125
- gz = Zlib::GzipWriter.new(buffer, 7, Zlib::DEFAULT_STRATEGY)
126
- File.open(tmx_path, "rb") { |_f| IO.copy_stream(_f, gz) }
127
- gz.finish
128
- buffer.rewind
129
-
130
- files = { "tmx" => Faraday::UploadIO.new(buffer, "application/gzip", "#{basename}.gz") }
131
- body = { "compression" => "gzip" }
151
+ mime_type = gzip ? "application/gzip" : "application/xml"
152
+ files = { "tmx" => Faraday::UploadIO.new(tmx_path, mime_type, basename) }
153
+ body = {}
154
+ body["compression"] = "gzip" if gzip
132
155
  body["callback_url"] = callback_url if callback_url
133
156
  Lara::Models::MemoryImport.new(**@client.post("/v2/memories/#{id}/import",
134
157
  body: body, files: files).transform_keys(&:to_sym))
@@ -166,5 +189,11 @@ module Lara
166
189
  end
167
190
  current
168
191
  end
192
+
193
+ private
194
+
195
+ def memory_from(response)
196
+ Lara::Models::Memory.new(**response.transform_keys(&:to_sym))
197
+ end
169
198
  end
170
199
  end
@@ -16,7 +16,8 @@ module Lara
16
16
  @created_at = Base.parse_time(created_at)
17
17
  @updated_at = Base.parse_time(updated_at)
18
18
  @shared_at = Base.parse_time(shared_at)
19
- @is_personal = is_personal
19
+ # The API sends is_personal: true and omits the key otherwise; it never sends false or null.
20
+ @is_personal = is_personal || false
20
21
  end
21
22
  end
22
23
 
@@ -21,7 +21,8 @@ module Lara
21
21
  @secret = secret
22
22
  @collaborators_count = collaborators_count
23
23
  @shared_at = Base.parse_time(shared_at)
24
- @is_personal = is_personal
24
+ # The API sends is_personal: true and omits the key otherwise; it never sends false or null.
25
+ @is_personal = is_personal || false
25
26
  end
26
27
  end
27
28
 
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Lara
6
+ module Models
7
+ class ResourceShareEntry < Base
8
+ attr_reader :id, :name, :share_name, :shared_at, :permissions
9
+
10
+ def initialize(id:, name:, share_name:, shared_at:, permissions:, **_kwargs)
11
+ super()
12
+ @id = id
13
+ @name = name
14
+ @share_name = share_name
15
+ @shared_at = Base.parse_time(shared_at)
16
+ @permissions = permissions
17
+ end
18
+ end
19
+
20
+ class MemoryShares < Base
21
+ attr_reader :memory, :account, :groups, :users
22
+
23
+ def initialize(memory:, account: nil, groups: [], users: [], **_kwargs)
24
+ super()
25
+ @memory = Memory.new(**memory.transform_keys(&:to_sym))
26
+ @account = ResourceShareEntry.new(**account.transform_keys(&:to_sym)) if account
27
+ @groups = groups.map { |entry| ResourceShareEntry.new(**entry.transform_keys(&:to_sym)) }
28
+ @users = users.map { |entry| ResourceShareEntry.new(**entry.transform_keys(&:to_sym)) }
29
+ end
30
+ end
31
+
32
+ class GlossaryShares < Base
33
+ attr_reader :glossary, :account, :groups, :users
34
+
35
+ def initialize(glossary:, account: nil, groups: [], users: [], **_kwargs)
36
+ super()
37
+ @glossary = Glossary.new(**glossary.transform_keys(&:to_sym))
38
+ @account = ResourceShareEntry.new(**account.transform_keys(&:to_sym)) if account
39
+ @groups = groups.map { |entry| ResourceShareEntry.new(**entry.transform_keys(&:to_sym)) }
40
+ @users = users.map { |entry| ResourceShareEntry.new(**entry.transform_keys(&:to_sym)) }
41
+ end
42
+ end
43
+
44
+ class StyleguideShares < Base
45
+ attr_reader :styleguide, :account, :groups, :users
46
+
47
+ def initialize(styleguide:, account: nil, groups: [], users: [], **_kwargs)
48
+ super()
49
+ @styleguide = Styleguide.new(**styleguide.transform_keys(&:to_sym))
50
+ @account = ResourceShareEntry.new(**account.transform_keys(&:to_sym)) if account
51
+ @groups = groups.map { |entry| ResourceShareEntry.new(**entry.transform_keys(&:to_sym)) }
52
+ @users = users.map { |entry| ResourceShareEntry.new(**entry.transform_keys(&:to_sym)) }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -115,10 +115,10 @@ module Lara
115
115
  end
116
116
 
117
117
  class Styleguide < Base
118
- attr_reader :id, :name, :content, :owner_id, :created_at, :updated_at, :is_personal
118
+ attr_reader :id, :name, :content, :owner_id, :created_at, :updated_at, :shared_at, :is_personal
119
119
 
120
120
  def initialize(id:, name:, content: nil, owner_id: nil, created_at: nil, updated_at: nil,
121
- is_personal: nil, **_kwargs)
121
+ shared_at: nil, is_personal: nil, **_kwargs)
122
122
  super()
123
123
  @id = id
124
124
  @name = name
@@ -126,7 +126,9 @@ module Lara
126
126
  @owner_id = owner_id
127
127
  @created_at = Base.parse_time(created_at)
128
128
  @updated_at = Base.parse_time(updated_at)
129
- @is_personal = is_personal
129
+ @shared_at = Base.parse_time(shared_at)
130
+ # The API sends is_personal: true and omits the key otherwise; it never sends false or null.
131
+ @is_personal = is_personal || false
130
132
  end
131
133
 
132
134
  def to_s
@@ -40,5 +40,40 @@ module Lara
40
40
  def delete(id)
41
41
  Lara::Models::Styleguide.new(**@client.delete("/v2/styleguides/#{id}").transform_keys(&:to_sym))
42
42
  end
43
+
44
+ # @return [Lara::Models::StyleguideShares]
45
+ def get_shares(id)
46
+ Lara::Models::StyleguideShares.new(**@client.get("/v2/styleguides/#{id}/shares").transform_keys(&:to_sym))
47
+ end
48
+
49
+ def add_account_share(id, name: nil)
50
+ styleguide_from(@client.post("/v2/styleguides/#{id}/shares", body: { name: name }.compact))
51
+ end
52
+
53
+ def rename_account_share(id, name:)
54
+ styleguide_from(@client.put("/v2/styleguides/#{id}/shares", body: { name: name }))
55
+ end
56
+
57
+ def revoke_account_share(id)
58
+ styleguide_from(@client.delete("/v2/styleguides/#{id}/shares"))
59
+ end
60
+
61
+ def add_group_share(id, group_id, name: nil)
62
+ styleguide_from(@client.post("/v2/styleguides/#{id}/shares/groups/#{group_id}", body: { name: name }.compact))
63
+ end
64
+
65
+ def rename_group_share(id, group_id, name:)
66
+ styleguide_from(@client.put("/v2/styleguides/#{id}/shares/groups/#{group_id}", body: { name: name }))
67
+ end
68
+
69
+ def revoke_group_share(id, group_id)
70
+ styleguide_from(@client.delete("/v2/styleguides/#{id}/shares/groups/#{group_id}"))
71
+ end
72
+
73
+ private
74
+
75
+ def styleguide_from(response)
76
+ Lara::Models::Styleguide.new(**response.transform_keys(&:to_sym))
77
+ end
43
78
  end
44
79
  end
data/lib/lara/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lara
4
- VERSION = "1.6.1"
4
+ VERSION = "1.8.0"
5
5
  end
data/lib/lara.rb CHANGED
@@ -19,6 +19,7 @@ require_relative "lara/models/base"
19
19
  require_relative "lara/models/text"
20
20
  require_relative "lara/models/memories"
21
21
  require_relative "lara/models/glossaries"
22
+ require_relative "lara/models/shares"
22
23
  require_relative "lara/models/documents"
23
24
  require_relative "lara/models/images"
24
25
  require_relative "lara/models/audio"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lara-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Translated
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-08-25 00:00:00.000000000 Z
11
+ date: 2026-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -165,6 +165,7 @@ files:
165
165
  - lib/lara/models/glossaries.rb
166
166
  - lib/lara/models/images.rb
167
167
  - lib/lara/models/memories.rb
168
+ - lib/lara/models/shares.rb
168
169
  - lib/lara/models/text.rb
169
170
  - lib/lara/s3_client.rb
170
171
  - lib/lara/styleguides.rb