de2p/meow.py

141 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (C) 2020 Alibek Omarov
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import requests
import json
import sys
import os
import re
from optparse import OptionParser
DISCORD_API_GUILD = 'https://discordapp.com/api/v6/guilds/%s'
DISCORD_CDN_EMOJI = 'https://cdn.discordapp.com/emojis/%s.%s'
def die(msg):
print(msg)
sys.exit(1)
def discord_api_get(url, headers):
print('API GET %s' % url)
r = requests.get(url, headers = headers)
return json.loads(r.text)
def discord_cdn_get(url, out, force):
if os.path.exists(out) and not force:
print('Skipping %s, already exists' % out)
return
print('CDN GET %s -> %s' % (url, out))
r = requests.get(url, allow_redirects=True)
open(out, 'wb').write(r.content)
def main(token, guild, force = False, out = None, include = None, exclude = None, ua = None):
if out is None:
out = guild
try:
os.mkdir(out)
except FileExistsError:
if not force:
die('Directory %s already exists' % out)
headers = { 'Authorization': token }
if ua != None:
headers['User-Agent'] = ua
guildinfo = discord_api_get(DISCORD_API_GUILD % guild, headers)
emojilist = guildinfo['emojis']
packjson = {
'files': {},
'pack': {
'description': 'Emojis from Discord server %s' % guildinfo['name'],
'license': 'Unknown', # did you asked author permission? I didn't. :(
'homepage': 'https://example.org', # fill with invite if you want to
'share-files': True # I don't know what it means
}
}
regex = None
if include != None:
is_include = True
regex = re.compile(include)
elif exclude != None:
is_include = False
regex = re.compile(exclude)
for emoji in emojilist:
name = emoji['name']
if regex != None:
if (regex.search(name) != None) != is_include:
print('Skipping %s, %s match regex' % (name, 'doesn\'t' if is_include else 'does'))
continue
animated = emoji['animated']
id = emoji['id']
ext = 'gif' if animated else 'png'
discord_cdn_get(DISCORD_CDN_EMOJI % (id, ext), os.path.join(out, name + '.' + ext), force)
packjson['files'][name] = name + '.' + ext
if len(packjson['files']) == 0:
die('Server doesn\'t have emojis or they were excluded by regular expression')
# always write pack.json for consistency
print('Writing pack.json...')
open(os.path.join(out, 'pack.json'), 'w').write(json.dumps(packjson))
print('Done!')
return 0
if __name__ == '__main__':
import config # to be filled by user
parser = OptionParser()
parser.add_option('-g', '--guild', action='store', dest='guild',
help='server to scrap emojis from')
parser.add_option('-o', '--out', action='store', dest='out',
help='result emojipack name')
parser.add_option('-f', '--force', action='store_true', dest='force',
help='ignore existing files')
parser.add_option('-i', '--include', action='store', dest='inc',
help='download emojis matching regular expression(incompatible with -x)')
parser.add_option('-x', '--exclude', action='store', dest='exc',
help='exclude emojis matching regular expression(incompatible with -i)')
(options, args) = parser.parse_args()
if options.guild is None:
die('Enter guild ID')
if len(config.AUTHORIZATION_TOKEN) == 0:
die('Enter authorization token in config.py')
sys.exit(main(
config.AUTHORIZATION_TOKEN,
options.guild,
options.force,
options.out,
options.inc,
options.exc,
config.USER_AGENT))