Last active
March 27, 2021 18:05
-
-
Save hellcp/44ce8ab2818c418debfd6f7bf0b7ed4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'mediawiki_api' | |
require 'discordrb' | |
require 'rmagick' | |
require 'open-uri' | |
require 'rexml/document' | |
require 'digest' | |
def lgbta_get_image_url(query) | |
client = MediawikiApi::Client.new 'https://lgbta.wikia.org/api.php' | |
result = client.query(srsearch: query, list: :search).data['search'].first | |
pageid = result['pageid'] if result | |
info = client.prop(:info, generator: :allpages, inprop: :url, gapfrom: result['title']).data['pages'][result['pageid'].to_s] if pageid | |
return { url: client.action(:imageserving, wisId: result['pageid']).data['image']['imageserving'], title: info['title'], link: info['fullurl'] } if info | |
{} | |
end | |
def path_props(svg) | |
drawing = Magick::Draw.new | |
canvas = Magick::Image.new(1500,1500) | |
doc = REXML::Document.new(File.open(svg).read) | |
path = doc.root.find_first_recursive {|node| node.name == 'path' }['d'] | |
drawing.path path | |
drawing.draw canvas | |
canvas.trim! | |
{ path: path, x: canvas.page.x, y: canvas.page.y, width: canvas.columns, height: canvas.rows } | |
end | |
def img_props(url) | |
file = URI.open(url).read | |
canvas = Magick::ImageList.new | |
canvas.from_blob(file).first | |
{ width: canvas.columns, height: canvas.rows } | |
end | |
bot = Discordrb::Commands::CommandBot.new token: ENV['DISCORD_TOKEN'], prefix: '!' | |
bot.command :sp do |event, *args| | |
return "I need sitelen pona symbol to render" if args.length == 0 | |
sitelen = { name: args.shift.gsub(/[^a-z]/, '') } | |
return "Not a sitelen pona symbol that I know" unless File.file?("linja_pimeja/#{sitelen[:name]}.svg") | |
background = { url: nil } | |
query = args.join.chomp | |
if query == '' | |
return "You either need to upload an image or tell me what flag to use as a background" unless event.message.attachments | |
event.message.attachments.each do |attachment| | |
background[:url] = attachment.url if URI.open(attachment.url).content_type.include? 'image' | |
end | |
return "You need to upload an image or tell me what flag to use as a background" unless background[:url] | |
elsif query.include?('//') && !query.include?(' ') | |
background[:url] = query | |
else | |
background.merge!(lgbta_get_image_url(query)) | |
return "Didn't find anything for the term `#{query}`" if background[:url].nil? | |
end | |
digest = Digest::SHA2.hexdigest("#{sitelen[:name]}+#{background[:url]}") | |
unless File.file?("tmp/#{digest}.png") | |
background[:file] = URI.open(background[:url]) | |
background.merge!(img_props(background[:url])) | |
sitelen.merge!(path_props("linja_pimeja/#{sitelen[:name]}.svg")) | |
svg_size = 825 | |
svg_size = sitelen[:width] if sitelen[:width] > svg_size | |
svg_size = sitelen[:height] if sitelen[:height] > svg_size | |
w_ratio = sitelen[:width].to_f / background[:width] | |
h_ratio = sitelen[:height].to_f / background[:height] | |
ratio = w_ratio > h_ratio ? w_ratio : h_ratio | |
background.merge!({ width: (background[:width] * ratio).ceil, height: (background[:height] * ratio).ceil }) | |
path = REXML::Element.new('path') | |
path.add_attribute('d', sitelen[:path]) | |
clipPath = REXML::Element.new('clipPath') | |
clipPath.add_attribute('id', 'mask') | |
clipPath.add(path) | |
zero = { x: sitelen[:x] - ((svg_size - sitelen[:width]) / 2), y: sitelen[:y] - ((svg_size - sitelen[:height]) / 2) } | |
image = REXML::Element.new('image') | |
image.add_attribute('clip-path', 'url(#mask)') | |
image.add_attribute('xlink:href', "data:#{background[:file].content_type};base64,#{Base64.strict_encode64(background[:file].read)}") | |
image.add_attribute('width', background[:width]) | |
image.add_attribute('height', background[:height]) | |
image.add_attribute('x', sitelen[:x] - (background[:width] - sitelen[:width]) / 2) | |
image.add_attribute('y', sitelen[:y] - (background[:height] - sitelen[:height]) / 2) | |
doc = REXML::Document.new("<svg version=\"1.1\" viewBox=\"#{zero[:x]} #{zero[:y]} #{svg_size} #{svg_size}\" width=\"1024\" height=\"1024\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"></svg>") | |
doc.root.add(clipPath) | |
doc.root.add(image) | |
img, _ = Magick::Image.from_blob(doc.to_s) { | |
self.format = 'SVG' | |
self.background_color = 'transparent' | |
} | |
png = img.write("tmp/#{digest}.png") | |
end | |
event.send_embed('', nil, [File.open("tmp/#{digest}.png")]) do |embed| | |
embed.title = sitelen[:name] | |
embed.title += " #{background[:title]}" if background[:title] | |
embed.url = background[:link] if background[:link] | |
embed.image = Discordrb::Webhooks::EmbedImage.new(url: "attachment://#{digest}.png") | |
end | |
end | |
bot.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment