about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-08-26 16:53:06 +0200
committerGitHub <noreply@github.com>2018-08-26 16:53:06 +0200
commitb378b4c5c7e99de2c14e39e2733a745689de8ad1 (patch)
treea393ed521b974921e1819cee3d40fd82a4cdf06d
parent5129f6f2aa56afb21708aec552a798d062ccaff9 (diff)
Add CLI interface for importing custom emoji (#8437)
bin/tootctl emoji import PATH_TO_TAR

Fix #8435
-rw-r--r--lib/cli.rb4
-rw-r--r--lib/mastodon/cli_helper.rb8
-rw-r--r--lib/mastodon/emoji_cli.rb81
-rw-r--r--lib/mastodon/media_cli.rb18
4 files changed, 106 insertions, 5 deletions
diff --git a/lib/cli.rb b/lib/cli.rb
index 7e82806b6..c7dae0276 100644
--- a/lib/cli.rb
+++ b/lib/cli.rb
@@ -2,10 +2,14 @@
 
 require 'thor'
 require_relative 'mastodon/media_cli'
+require_relative 'mastodon/emoji_cli'
 
 module Mastodon
   class CLI < Thor
     desc 'media SUBCOMMAND ...ARGS', 'manage media files'
     subcommand 'media', Mastodon::MediaCLI
+
+    desc 'emoji SUBCOMMAND ...ARGS', 'manage custom emoji'
+    subcommand 'emoji', Mastodon::EmojiCLI
   end
 end
diff --git a/lib/mastodon/cli_helper.rb b/lib/mastodon/cli_helper.rb
new file mode 100644
index 000000000..8c4d9731c
--- /dev/null
+++ b/lib/mastodon/cli_helper.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+dev_null = Logger.new('/dev/null')
+
+Rails.logger                 = dev_null
+ActiveRecord::Base.logger    = dev_null
+HttpLog.configuration.logger = dev_null
+Paperclip.options[:log]      = false
diff --git a/lib/mastodon/emoji_cli.rb b/lib/mastodon/emoji_cli.rb
new file mode 100644
index 000000000..71f8b2cc7
--- /dev/null
+++ b/lib/mastodon/emoji_cli.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'rubygems/package'
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+# rubocop:disable Rails/Output
+
+module Mastodon
+  class EmojiCLI < Thor
+    option :prefix
+    option :suffix
+    option :overwrite, type: :boolean
+    option :unlisted, type: :boolean
+    desc 'import PATH', 'import emoji from a TAR archive at PATH'
+    long_desc <<-LONG_DESC
+      Imports custom emoji from a TAR archive specified by PATH.
+
+      Existing emoji will be skipped unless the --overwrite option
+      is provided, in which case they will be overwritten.
+
+      With the --prefix option, a prefix can be added to all
+      generated shortcodes. Likewise, the --suffix option controls
+      the suffix of all shortcodes.
+
+      With the --unlisted option, the processed emoji will not be
+      visible in the emoji picker (but still usable via other means)
+    LONG_DESC
+    def import(path)
+      imported = 0
+      skipped  = 0
+      failed   = 0
+
+      Gem::Package::TarReader.new(Zlib::GzipReader.open(path)) do |tar|
+        tar.each do |entry|
+          next unless entry.file? && entry.full_name.end_with?('.png')
+
+          shortcode    = [options[:prefix], File.basename(entry.full_name, '.*'), options[:suffix]].compact.join
+          custom_emoji = CustomEmoji.local.find_by(shortcode: shortcode)
+
+          if custom_emoji && !options[:overwrite]
+            skipped += 1
+            next
+          end
+
+          custom_emoji ||= CustomEmoji.new(shortcode: shortcode, domain: nil)
+          custom_emoji.image = StringIO.new(entry.read)
+          custom_emoji.image_file_name = File.basename(entry.full_name)
+          custom_emoji.visible_in_picker = !options[:unlisted]
+
+          if custom_emoji.save
+            imported += 1
+          else
+            failed += 1
+            say('Failure/Error: ', :red)
+            say(entry.full_name)
+            say('    ' + custom_emoji.errors[:image].join(', '), :red)
+          end
+        end
+      end
+
+      puts
+      say("Imported #{imported}, skipped #{skipped}, failed to import #{failed}", color(imported, skipped, failed))
+    end
+
+    private
+
+    def color(green, _yellow, red)
+      if !green.zero? && red.zero?
+        :green
+      elsif red.zero?
+        :yellow
+      else
+        :red
+      end
+    end
+  end
+end
+
+# rubocop:enable Rails/Output
diff --git a/lib/mastodon/media_cli.rb b/lib/mastodon/media_cli.rb
index cc6ad07d9..00bd662f4 100644
--- a/lib/mastodon/media_cli.rb
+++ b/lib/mastodon/media_cli.rb
@@ -2,6 +2,7 @@
 
 require_relative '../../config/boot'
 require_relative '../../config/environment'
+require_relative 'cli_helper'
 
 # rubocop:disable Rails/Output
 
@@ -23,8 +24,9 @@ module Mastodon
       the underlying file storage.
     DESC
     def remove
-      time_ago = options[:days].days.ago
-      queued   = 0
+      time_ago  = options[:days].days.ago
+      queued    = 0
+      processed = 0
 
       MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).select(:id).reorder(nil).find_in_batches do |media_attachments|
         if options[:background]
@@ -33,13 +35,19 @@ module Mastodon
         else
           media_attachments.each do |m|
             Maintenance::UncacheMediaWorker.new.perform(m)
-            print '.'
+            say('.', :green, false)
+            processed += 1
           end
         end
       end
 
-      puts
-      puts "Scheduled the deletion of #{queued} media attachments" if options[:background]
+      say
+
+      if options[:background]
+        say("Scheduled the deletion of #{queued} media attachments", :green)
+      else
+        say("Removed #{processed} media attachments", :green)
+      end
     end
   end
 end