Module: Micompress

Defined in:
lib/micompress.rb,
lib/micompress/client.rb,
lib/micompress/version.rb,
lib/micompress/categories.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

DEFAULT_BASE =
"https://micompress.com"
UTM =
"utm_source=rubygems&utm_medium=cli&utm_campaign=extend"
USER_AGENT =
"micompress-ruby/#{VERSION} (+https://micompress.com)"
VERSION =
"0.1.0"
EXT_CATEGORY =

File extension -> MiCompress category. Mirrors services/formatDetector.js.

{
  "jpg" => "image", "jpeg" => "image", "png" => "image", "webp" => "image", "gif" => "image",
  "bmp" => "image", "tiff" => "image", "tif" => "image", "avif" => "image", "svg" => "image",
  "heic" => "image", "heif" => "image", "ico" => "image", "psd" => "image", "dng" => "image",
  "raw" => "image", "cr2" => "image", "arw" => "image", "nef" => "image",
  "mp4" => "video", "mov" => "video", "avi" => "video", "mkv" => "video", "webm" => "video",
  "mpeg" => "video", "mpg" => "video", "m4v" => "video", "wmv" => "video", "flv" => "video", "3gp" => "video",
  "mp3" => "audio", "wav" => "audio", "flac" => "audio", "ogg" => "audio", "m4a" => "audio",
  "aac" => "audio", "wma" => "audio", "opus" => "audio",
  "pdf" => "pdf",
  "csv" => "document", "json" => "document", "xml" => "document", "md" => "document",
  "odt" => "document", "ods" => "document", "docx" => "document", "doc" => "document",
  "ppt" => "document", "pptx" => "document", "xls" => "document", "xlsx" => "document",
  "epub" => "document", "html" => "document", "htm" => "document", "hwp" => "document",
  "txt" => "document", "rtf" => "document",
  "zip" => "archive", "7z" => "archive", "tar" => "archive", "gz" => "archive", "tgz" => "archive", "rar" => "archive"
}.freeze
CATEGORY_PATH =
{
  "image" => "image-compressors", "video" => "video-compressors", "audio" => "audio-compressors",
  "document" => "document-compressors", "pdf" => "pdf-compressors", "archive" => "archive-compressors"
}.freeze

Class Method Summary collapse

Class Method Details

.category_for(filename) ⇒ Object



35
36
37
# File 'lib/micompress/categories.rb', line 35

def category_for(filename)
  EXT_CATEGORY[ext_of(filename)]
end

.compress_file(path, base_url: DEFAULT_BASE, preset: "recommended", max_width: nil, token: nil) ⇒ Object

Compress a single file. Returns [bytes, meta_hash].

Raises:



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
# File 'lib/micompress/client.rb', line 16

def self.compress_file(path, base_url: DEFAULT_BASE, preset: "recommended", max_width: nil, token: nil)
  base = base_url.chomp("/")
  filename = File.basename(path)
  category = category_for(filename)
  raise Error, "Unsupported file type \".#{ext_of(filename) || '?'}\". See #{base}/all-tools" unless category
  raise Error, "File not found: #{path}" unless File.file?(path)

  uri = URI("#{base}/#{endpoint_path(category)}/compress")
  req = Net::HTTP::Post.new(uri)
  req["Accept"] = "application/json"
  req["User-Agent"] = USER_AGENT
  req["Authorization"] = "Bearer #{token}" if token

  form = [["file", File.open(path, "rb"), { filename: filename, content_type: "application/octet-stream" }],
          ["preset", preset]]
  form << ["maxWidth", max_width.to_s] if max_width
  req.set_form(form, "multipart/form-data")

  json = request_json(uri, req)
  unless json["success"] && json["downloadUrl"]
    raise Error, (json["error"] || "Compression failed")
  end

  bytes = download("#{base}#{json['downloadUrl']}", token)
  [bytes, json]
end

.download(url, token) ⇒ Object

Raises:



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/micompress/client.rb', line 53

def self.download(url, token)
  uri = URI(url)
  req = Net::HTTP::Get.new(uri)
  req["User-Agent"] = USER_AGENT
  req["Authorization"] = "Bearer #{token}" if token
  res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
    http.read_timeout = 120
    http.request(req)
  end
  raise Error, "Download failed (HTTP #{res.code})" unless res.is_a?(Net::HTTPSuccess)
  res.body
end

.endpoint_path(category) ⇒ Object



39
40
41
# File 'lib/micompress/categories.rb', line 39

def endpoint_path(category)
  CATEGORY_PATH[category]
end

.ext_of(filename) ⇒ Object



30
31
32
33
# File 'lib/micompress/categories.rb', line 30

def ext_of(filename)
  ext = File.extname(filename.to_s).sub(".", "").downcase
  ext.empty? ? nil : ext
end

.request_json(uri, req) ⇒ Object



43
44
45
46
47
48
49
50
51
# File 'lib/micompress/client.rb', line 43

def self.request_json(uri, req)
  res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
    http.read_timeout = 120
    http.request(req)
  end
  JSON.parse(res.body)
rescue JSON::ParserError
  raise Error, "Unexpected response (HTTP #{res&.code})"
end