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
132
133
134
135
136
137
138
139
140
141
142
|
# frozen_string_literal: true
require 'rubygems/package'
require_relative '../../config/boot'
require_relative '../../config/environment'
require_relative 'cli_helper'
module Mastodon
class EmojiCLI < Thor
def self.exit_on_failure?
true
end
option :prefix
option :suffix
option :overwrite, type: :boolean
option :unlisted, type: :boolean
option :category
desc 'import PATH', 'Import emoji from a TAR GZIP archive at PATH'
long_desc <<-LONG_DESC
Imports custom emoji from a TAR GZIP archive specified by PATH.
Existing emoji will be skipped unless the --overwrite option
is provided, in which case they will be overwritten.
You can specify a --category under which the emojis will be
grouped together.
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
category = options[:category] ? CustomEmojiCategory.find_or_create_by(name: options[:category]) : nil
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]
custom_emoji.category = category
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
option :category
option :overwrite, type: :boolean
desc 'export PATH', 'Export emoji to a TAR GZIP archive at PATH'
long_desc <<-LONG_DESC
Exports custom emoji to 'export.tar.gz' at PATH.
The --category option dumps only the specified category.
If this option is not specified, all emoji will be exported.
The --overwrite option will overwrite an existing archive.
LONG_DESC
def export(path)
exported = 0
category = CustomEmojiCategory.find_by(name: options[:category])
export_file_name = File.join(path, 'export.tar.gz')
if File.file?(export_file_name) && !options[:overwrite]
say("Archive already exists! Use '--overwrite' to overwrite it!")
exit 1
end
if category.nil? && options[:category]
say("Unable to find category '#{options[:category]}'!")
exit 1
end
File.open(export_file_name, 'wb') do |file|
Zlib::GzipWriter.wrap(file) do |gzip|
Gem::Package::TarWriter.new(gzip) do |tar|
scope = !options[:category] || category.nil? ? CustomEmoji.local : category.emojis
scope.find_each do |emoji|
say("Adding '#{emoji.shortcode}'...")
tar.add_file_simple(emoji.shortcode + File.extname(emoji.image_file_name), 0o644, emoji.image_file_size) do |io|
io.write Paperclip.io_adapters.for(emoji.image).read
exported += 1
end
end
end
end
end
say("Exported #{exported}")
end
option :remote_only, type: :boolean
desc 'purge', 'Remove all custom emoji'
long_desc <<-LONG_DESC
Removes all custom emoji.
With the --remote-only option, only remote emoji will be deleted.
LONG_DESC
def purge
scope = options[:remote_only] ? CustomEmoji.remote : CustomEmoji
scope.in_batches.destroy_all
say('OK', :green)
end
private
def color(green, _yellow, red)
if !green.zero? && red.zero?
:green
elsif red.zero?
:yellow
else
:red
end
end
end
end
|