Ejemplo n.º 1
0
async def search(*tags: str):
    """seraches derpibooru"""
    try:
        imgs = [img for img in Search().query(*tags).sort_by(sort.RANDOM)]
        url = imgs[0].full
        await bot.say(url)
    except:
        await bot.say("Invalid search term")
Ejemplo n.º 2
0
def main():
    logger = logging.getLogger("derpiboorudl")
    setup_logger(logger)

    # Parse args
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-d",
        "--destdir",
        required=True,
        help="Location where downloaded images will be dropped off")
    parser.add_argument("-q",
                        "--query",
                        default="",
                        help="The Derpibooru query you wish to execute")
    parser.add_argument("-c",
                        "--count",
                        default=100,
                        help="The count of images you wish to download",
                        type=int)
    parser.add_argument(
        "-k",
        "--key",
        default=None,
        help="Specify the API key (normally present as env variable)")
    args = parser.parse_args()

    destdir, query, maximages = args.destdir, args.query, args.count

    # Read API key from --key if present or else read from env
    apikey = args.key if args.key else os.getenv("DERPIBOORUAPIKEY")

    if not apikey:
        logger.info("No API key was set! (DERPIBOORUAPIKEY)")

    search = Search().key(apikey).query(query).limit(maximages)

    if not os.path.isdir(destdir):
        os.mkdir(destdir)

    for image in search:
        filename = os.path.basename(image.full)
        path = os.path.join(destdir, filename)
        if not os.path.isfile(path):
            logger.info("Now downloading image with id {0}".format(
                image.id_number))

            download = download_file(image.full)
            if download:
                if image.sha512_hash == sha512_hash(download):
                    with open(path, "wb") as f:
                        f.write(download)
                else:
                    logger.error("sha512 hashes for {0} don't match up".format(
                        image.id_number))
            else:
                logger.error("download for {0} didn't complete".format(
                    image.id_number))
Ejemplo n.º 3
0
def test_query():
  """
  Tests whether the results in a query contain the tag that was being searched
  for
  """
  limit, tag = 10, "sunset shimmer"
  images = [image for image in Search().query(tag).limit(limit)]

  assert len(images) == limit

  for image in images:
    assert tag in image.tags
Ejemplo n.º 4
0
def test_descending():
  """
  Tests whether descending search is in the correct order
  """
  limit = 10
  images = [image for image in Search().descending().limit(limit)]

  assert len(images) == limit

  for image in images:
  # Check if the image IDs are listed in descending order
  # by comparing the ID of the next image
    if image is not images[-1]:
      next_image = images[images.index(image) + 1]
      assert image.id_number > next_image.id_number
Ejemplo n.º 5
0
def send_art(chat_id):
    if os.path.isfile(LOCKER):
        return
    open(LOCKER, 'w').close()
    with open(BAYANS) as b:
        bayan_ids = set(b.read().split())
    N = 10
    while True:
        for pic in Search().sort_by(sort.SCORE).limit(N)\
                .query("first_seen_at.gt:30 days ago", "safe", "-animated", "-comic", "-screencap", "-anthro"):
            if pic.id not in bayan_ids:
                bot.send_photo(chat_id, pic.large)
                with open(BAYANS, 'a') as b:
                    b.write(pic.id + '\n')
                os.remove(LOCKER)
                print("Anti-Hibonicus art sent!")
                return
        N *= 3
Ejemplo n.º 6
0
async def on_message(message):
    #Event for when message gets recieved
    if not message.server: #DMs
        if message.author == client.user:
            return
        if message.content.startswith(COMMAND_PREFIX):
            command = message.content.split(' ' , maxsplit=1)
            
            if command[0] == COMMAND_PREFIX+'mute':
                await cog_notifications.mute(client, message)

            if command[0] == COMMAND_PREFIX+'unmute':
                await cog_notifications.unmute(client, message)
        else:
            print('({1.hour:02d}:{1.minute:02d}){0.author.name} send us a message in DM.'.format(message, datetime.now()))
            print('\"{0.author.name}:{0.clean_content}\"'.format(message))
            #await client.send_message(client.get_channel('303603185514184705'), '{0.author.name}(`{0.author.id}`) send me a message in DM. He said:\n"{0.clean_content}"'.format(message))
    if message.server: #not DMs
        if message.server.id in authorized_servers:
            #Accessing global variables with ability to write
            global DERPIBOORU_ENABLED
            global EQD_FEED_ENABLED
            global MEME_ENABLED
            global ME_ENABLED
            global MENTION_ENABLED
            global undo_posts
            global derpi_undo_posts
            global meme_timer
            global mention_timer
            global derpi_timer

            if message.channel.id in meme_commands: #For commands in meme channel
                if message.content.startswith(COMMAND_PREFIX):
                    command = message.content.split(' ' , maxsplit=1)

                    if command[0] == COMMAND_PREFIX+'undo': #Pmeme undo command. Deletes last pmeme message sender got
                        print('({1.hour:02d}:{1.minute:02d}) undo command by {0}'.format(message.author.name, datetime.now()))
                        for msg, user in reversed(undo_posts):
                            if user == message.author:
                                await client.delete_message(msg)
                                undo_posts.remove((msg, user))
                                #print([i[1] for i in undo_posts])
                                return
                        await client.send_message(message.channel, 'Nothing to undo for you, silly')
                        print('nothing to undo')
                            
                    if command[0] == COMMAND_PREFIX+'pmeme': #Pmeme command. Gets a random derpi image tagged "meme"
                        if not MEME_ENABLED:
                            await client.send_message(message.channel, random.choice(command_off_quotes))
                            return
                        if len(command) == 1:
                            meme_query = ''
                        else:
                            meme_query = command[1]
                        print('({1.hour:02d}:{1.minute:02d}) pmeme command by {0} with tags "{2}"'.format(message.author.name, datetime.now(), meme_query))
                        if meme_timer.is_alive():
                            await client.send_message(message.channel, random.choice(cooldown_quotes))
                            print('pmeme cooldown'.format(datetime.now()))
                            return
                        if message.channel.id not in commands_channels:
                            meme_timer = Timer(MEME_COOLDOWN, empty) #cooldown
                            meme_timer.start()
                        for image in Search().sort_by(sort.RANDOM).query(meme_query).filter(DERPI_MEME_FILTER):
                            msg = await client.send_message(message.channel, image.url)
                            undo_posts.append((msg, message.author))
                            if len(undo_posts) > 10:
                                undo_posts.pop(0)
                            #print(undo_posts)
                            return
                        await client.send_message(message.channel, "I can't find anything")
                        meme_timer.cancel()
                        print('nothing found')
            
            if message.channel.id in art_commands: #For commands in art channel
                if message.content.startswith(COMMAND_PREFIX):
                    command = message.content.split(' ' , maxsplit=1)

                    if command[0] == COMMAND_PREFIX+'undo': #pony undo command. Deletes last ponyr or pony message sender got
                        print('({1.hour:02d}:{1.minute:02d}) undo command by {0}'.format(message.author.name, datetime.now()))
                        for msg, user in reversed(derpi_undo_posts):
                            if user == message.author:
                                await client.delete_message(msg)
                                derpi_undo_posts.remove((msg, user))
                                #print(derpi_undo_posts)
                                return
                        await client.send_message(message.channel, 'Nothing to undo for you, silly')
                        print('nothing to undo')
            
                    if command[0] == COMMAND_PREFIX+'ponyr': #Ponyr command. Gets a random derpi image with or without user tags.
                        if not DERPIBOORU_ENABLED:
                            await client.send_message(message.channel, random.choice(command_off_quotes))
                            return
                        derpi_filter = DERPI_GENERAL_FILTER
                        if len(command) == 1:
                            derpi_query = ''
                        else:
                            derpi_query = command[1]
                            if command[1].find('artist:') != -1:
                                derpi_filter = DERPI_GENERAL_ARTIST_FILTER
                        print('({1.hour:02d}:{1.minute:02d}) Pony with tags:"{0}"'.format(derpi_query, datetime.now()))
                        if derpi_timer.is_alive():
                            await client.send_message(message.channel, random.choice(cooldown_quotes))
                            print('ponyr cooldown'.format(datetime.now()))
                            return
                        if message.channel.id not in commands_channels:
                            derpi_timer = Timer(DERPI_COOLDOWN, empty)
                            derpi_timer.start()
                        for image in Search().sort_by(sort.RANDOM).query(derpi_query).filter(filter_id=derpi_filter):
                            msg = await client.send_message(message.channel, image.url)
                            derpi_undo_posts.append((msg, message.author))
                            if len(derpi_undo_posts) > 10:
                                derpi_undo_posts.pop(0)
                            #print(derpi_undo_posts)
                            return                        
                        await client.send_message(message.channel, "I can't find anything")
                        derpi_timer.cancel()
                        print('nothing found')
                        
                    if command[0] == COMMAND_PREFIX+'pony': #Pony command. Gets newest derpi image with or without user tags.
                        if not DERPIBOORU_ENABLED:
                            await client.send_message(message.channel, random.choice(command_off_quotes))
                            return
                        derpi_filter = DERPI_GENERAL_FILTER
                        if len(command) == 1:
                            derpi_query = ''
                        else:
                            derpi_query = command[1]
                            if command[1].find('artist:') != -1:
                                derpi_filter = DERPI_GENERAL_ARTIST_FILTER
                        print('({1.hour:02d}:{1.minute:02d}) Pony with tags:"{0}"'.format(derpi_query, datetime.now()))
                        if derpi_timer.is_alive():
                            await client.send_message(message.channel, random.choice(cooldown_quotes))
                            print('pony cooldown'.format(datetime.now()))
                            return
                        if message.channel.id not in commands_channels:
                            derpi_timer = Timer(DERPI_COOLDOWN, empty)
                            derpi_timer.start()
                        for image in Search().query(derpi_query).filter(filter_id=derpi_filter):
                            msg = await client.send_message(message.channel, image.url)
                            derpi_undo_posts.append((msg, message.author))
                            if len(derpi_undo_posts) > 10:
                                derpi_undo_posts.pop(0)
                            #print([v.name for v in derpi_undo_posts.values()])
                            return
                        await client.send_message(message.channel, "I can't find anything")
                        derpi_timer.cancel()
                        print('nothing found')
            
            if message.channel.id in commands_channels: #For general (staff) commands. Preferably to add mod user filter
                if message.content.startswith(COMMAND_PREFIX):
                    command = message.content.split(' ' , maxsplit=1)


                    if command[0] == COMMAND_PREFIX+'mute': #Mute command. Mutes sub notifications
                        await cog_notifications.mute(client, message)

                    if command[0] == COMMAND_PREFIX+'unmute': #Unmute command. Unmutes sub notifications
                        await cog_notifications.unmute(client, message)

                    if command[0] == COMMAND_PREFIX+'subscribe': #Subscribe command. Adds your id to the list of recievers of something.
                        await cog_notifications.subscribe(client, message, command)

                    if command[0] == COMMAND_PREFIX+'unsubscribe': #Unsubscribe command. Removes your id form the list of recievers of something.
                        await cog_notifications.unsubscribe(client, message, command)
                        
                    if command[0] == COMMAND_PREFIX+'names': #Names command. Prints the last recorded 20 names and nicknames of a user.
                        await cog_commands.names(client, message, command)
                    
                    if command[0] == COMMAND_PREFIX+'togglemention': #Togglemention command. Enables/disables responce to a mention
                        MENTION_ENABLED = not MENTION_ENABLED
                        if MENTION_ENABLED:
                            await client.send_message(message.channel, 'Reaction to mentions is now enabled')
                        else:
                            await client.send_message(message.channel, 'Reaction to mentions is now disabled')

                    if command[0] == COMMAND_PREFIX+'togglememe': #Togglememe command. Enables/disables pmeme
                        MEME_ENABLED = not MEME_ENABLED
                        if MEME_ENABLED:
                            await client.send_message(message.channel, 'Meme commands are now enabled')
                        else:
                            await client.send_message(message.channel, 'Meme commands are now disabled')

                    if command[0] == COMMAND_PREFIX+'toggleme': #Togglememe command. Enables/disables me
                        ME_ENABLED = not ME_ENABLED
                        if ME_ENABLED:
                            await client.send_message(message.channel, 'Me command is now enabled')
                        else:
                            await client.send_message(message.channel, 'Me command is now disabled')


                    if command[0] == COMMAND_PREFIX+'me': #Me command. Makes bot say the message given in specified channel
                        if not ME_ENABLED:
                            return
                        if len(command) > 1:
                            me_command = command[1].split(' ', maxsplit=1)
                            print('({1.hour:02d}:{1.minute:02d}) me command with args {0}'.format((message.clean_content.split(' ' , maxsplit=1))[1], datetime.now()))
                            me_channel_id = me_command[0].strip('<>#!')
                            if len(me_command) > 1 and me_channel_id.isdecimal() and client.get_channel(me_channel_id) and me_channel_id not in serious_channels:
                                try:
                                    await client.send_typing(client.get_channel(me_channel_id))
                                    await asyncio.sleep(min(len(me_command[1])*0.05*random.uniform(0.8,1.1), 6)) #"Typing..." length formula
                                    await client.send_message(client.get_channel(me_channel_id), stop_mass_mentions(me_command[1]))
                                except discord.errors.Forbidden as e:
                                    await client.send_message(message.channel, 'I can\'t post there')
                                return
                        await client.send_message(message.channel, '```\n'+command[0]+' #channel <text_you_want_me_to_say>\n```')

                    if command[0] == COMMAND_PREFIX+'togglederpi': #Togglederpi command. Enables/disables pony and ponyr
                        DERPIBOORU_ENABLED = not DERPIBOORU_ENABLED
                        if DERPIBOORU_ENABLED:
                            await client.send_message(message.channel, 'Derpibooru commands are now enabled')
                        else:
                            await client.send_message(message.channel, 'Derpibooru commands are now disabled')

                    if command[0] == COMMAND_PREFIX+'togglefeed': #Togglefeed command. Enables/disables feed
                        EQD_FEED_ENABLED = not EQD_FEED_ENABLED
                        if EQD_FEED_ENABLED:
                            await client.send_message(message.channel, 'EQD feed is now enabled')
                        else:
                            await client.send_message(message.channel, 'EQD feed is now disabled')

                    if command[0] == COMMAND_PREFIX+'urban': #Urban command. Gets Urbandictionary definition for the word
                        if len(command) == 1:
                            return
                        print('({0.hour:02d}:{0.minute:02d}){1.author.name} used urban for word "{2}"'.format(datetime.now(), message, command[1]))
                        defs = ud.define(command[1])
                        if not defs:
                            print('Nothing found')
                            await client.send_message(message.channel, 'Nothing found')
                            return
                        n = 0
                        em = discord.Embed(title=defs[n].word, description=defs[n].definition.replace('[', '').replace(']', ''), colour=0x134FE6)
                        em.add_field(name='Example:', value=defs[n].example.replace('[', '').replace(']', ''))
                        em.set_footer(text='{0} at UTC/GMT+0'.format(datetime.utcnow()))
                        await client.send_message(message.channel, embed=em)

                    if command[0] == COMMAND_PREFIX+'urbanr': #UrbanR command. Gets random Urbandictionary word and its definition
                        defs = ud.random()
                        if not defs:
                            print('Urbanr Nothing found')
                            await client.send_message(message.channel, 'Nothing found')
                            return
                        n = 0
                        print('({0.hour:02d}:{0.minute:02d}){1.author.name} used urbanr and got the word "{2}"'.format(datetime.now(), message, defs[n].word))
                        em = discord.Embed(title=defs[n].word, description=defs[n].definition.replace('[', '').replace(']', ''), colour=0x134FE6)
                        em.add_field(name='Example:', value=defs[n].example.replace('[', '').replace(']', ''))
                        em.set_footer(text='{0} at UTC/GMT+0'.format(datetime.utcnow()))
                        await client.send_message(message.channel, embed=em)

                    if command[0] == COMMAND_PREFIX+'ping': #Ping command. Simply replies with pong. Used to check if bot is alive
                        print('({0.hour:02d}:{0.minute:02d}) pong'.format(datetime.now()))
                        await client.send_message(message.channel, 'pong')
                        
                    if command[0] == COMMAND_PREFIX+'reason': #Reason command. Logs the ban in ban channel with given case and reason.
                        await cog_banning.reason(client, message, command)
                            
                    if command[0] == COMMAND_PREFIX+'userinfo': #Userinfo command. Prints information about given user or sender, if no user given
                        if len(command) == 1:
                            userinfo_command = message.author.id
                        else:
                            userinfo_command = command [1]
                        print('({1.hour:02d}:{1.minute:02d}){0.author.name} used `userinfo command'.format(message, datetime.now()))
                        print('\"{0.author.name}:{0.content}\"'.format(message))
                        if userinfo_command.isdecimal():                        #by id
                            user = message.server.get_member(userinfo_command)
                        elif (userinfo_command.strip('<>@!')).isdecimal():      #by ping
                            user = message.server.get_member(userinfo_command.strip('<>@!'))
                        else:                                                   #by name
                            user = message.server.get_member_named(userinfo_command)
                        if not user:
                            await client.send_message(message.channel, 'User not found.\nUse \`userinfo <id/mention/name> to get info about user.')
                            return
                        if user.avatar_url:
                            user_avatar_url = user.avatar_url
                        else:
                            user_avatar_url = user.default_avatar_url
                        em = discord.Embed(title=':information_source: User info', colour=user.colour)
                        em.set_author(name='User: @{0.name}#{0.discriminator} - {0.id}'.format(user))
                        em.set_thumbnail(url=user_avatar_url)
                        em.add_field(name='User:'******'Nickname:', value=user.nick, inline=True)
                        em.add_field(name="User created on:", value=user.created_at.strftime("%d %b %Y %H:%M") + ' ({} days ago)  '.format((message.timestamp - user.created_at).days), inline=False)
                        em.add_field(name="User joined on:", value=user.joined_at.strftime("%d %b %Y %H:%M") + ' ({} days ago)'.format((message.timestamp - user.joined_at).days), inline=False)
                        if len(user.roles) > 1:
                            em.add_field(name="Roles:", value=", ".join([x.name for x in user.roles if x.name != "@everyone"]), inline=False)
                        em.set_footer(text='{0} at UTC/GMT+0'.format(datetime.utcnow()))
                        await client.send_message(message.channel, embed=em)
                        
                    if command[0] == COMMAND_PREFIX+'serverinfo': #Serverinfo command. Prints information about current server
                        print('({1.hour:02d}:{1.minute:02d}){0.author.name} used `serverinfo command'.format(message, datetime.now()))
                        print('\"{0.author.name}:{0.content}\"'.format(message))
                        em = discord.Embed(title=':information_source: Server info', colour=0x80A0EE)
                        em.set_author(name=message.server.name + ' - ' + message.server.id)
                        em.set_thumbnail(url=message.server.icon_url)
                        em.add_field(name='Members:', value=message.server.member_count)
                        em.add_field(name='Owner:', value=message.server.owner.mention)
                        ver_levels = {discord.VerificationLevel.none:'None - No criteria set.',
                                      discord.VerificationLevel.low:'Low - Member must have a verified email on their Discord account.',
                                      discord.VerificationLevel.medium:'Medium - Member must have a verified email and be registered on Discord for more than five minutes.',
                                      discord.VerificationLevel.high:'High - Member must have a verified email, be registered on Discord for more than five minutes, and be a member of the server itself for more than ten minutes.',
                                      discord.VerificationLevel.table_flip:'High - Member must have a verified email, be registered on Discord for more than five minutes, and be a member of the server itself for more than ten minutes.'}
                        em.add_field(name='Verification level:', value=ver_levels.get(message.server.verification_level, 'None'), inline=False)
                        em.add_field(name='Created on:', value=message.server.created_at.strftime("%d %b %Y %H:%M") + ' ({} days ago)'.format((message.timestamp - message.server.created_at).days), inline=False)
                        em.set_footer(text='{0} at UTC/GMT+0'.format(datetime.utcnow()))
                        await client.send_message(message.channel, embed=em)


            if message.server.me in message.mentions: #If someone mentions the bot
                if not MENTION_ENABLED:
                    return
                print('({1.hour:02d}:{1.minute:02d}){0.author.name} mentioned bot in {0.channel.name} at {0.server.name}.'.format(message, datetime.now()))
                print('\"{0.author.name}:{0.clean_content}\"'.format(message))
                if mention_timer.is_alive():
                    return
                if message.channel.id not in commands_channels:
                    mention_timer = Timer(MENTION_COOLDOWN, empty) #mention cooldown
                    mention_timer.start()

                rand = random.randint(5,15)
                if '?' in message.content:
                    rand_q = emojify(random.choice(ball8_quotes), message.server)
                elif ':boop:' in message.content:
                    rand_q = emojify(':boop:', message.server) + message.author.mention
                    print(rand_q)
                elif ':hugs:' in message.content:
                    rand_q = emojify(':hugs:', message.server) + message.author.mention
                else:
                    rand_q = emojify(random.choice(mention_quotes), message.server)
                print('And we answered in {0} sec with \"{1}\"'.format(rand, rand_q))
                await asyncio.sleep(rand)
                await client.send_message(message.channel, rand_q)
                
    if message.server:
        if message.server.id in authorized_servers:
            if message.channel.id not in serious_channels and message.channel.id != '151834220841533440': #staff
                for i in banned_words:
                    if i in message.content.lower():
                        if message.author.nick is None:
                            print('({1.hour:02d}:{1.minute:02d}){0.author.name} said banned word in #{0.channel.name} at {0.server.name}.'.format(message, datetime.now()))
                            print('\"{0.author.name}:{0.content}\"'.format(message))
                            dmsg = '{0.author.name}`({0.author.id})` said banned word in #{0.channel.name} at {0.server.name}.\n\"{0.author.name}:{0.content}\"'.format(message)
                            await cog_notifications.dispatch(client, 'banned words', dmsg)
                        else:
                            print('({1.hour:02d}:{1.minute:02d}){0.author.nick}({0.author.name}) said banned word in #{0.channel.name} at {0.server.name}.'.format(message, datetime.now()))
                            print('\"{0.author.nick}:{0.content}\"'.format(message))
                            dmsg = '{0.author.nick}({0.author.name})`({0.author.id})` said banned word in #{0.channel.name} at {0.server.name}.\n\"{0.author.nick}:{0.content}\"'.format(message)
                            await cog_notifications.dispatch(client, 'banned words', dmsg)
                        break
            
            if message.channel.id in general_channels:
                if message.attachments:
                    for i in message.attachments:
                        if i:
                            try:
                                if(i.get('width') is not None) and (i.get('height') > 128):
                                    if i.get('width') > 400:
                                        if (i.get('height')*0.75) < 128:
                                            break
                                    if message.author.nick is None:
                                        dmsg = '{0.author.name}`({0.author.id})` posted a picture({1}x{2}) in #{0.channel.name} at {0.server.name}.'.format(message, i.get('width'),i.get('height'))
                                        print('({0.hour:02d}:{0.minute:02d})'.format(datetime.now())+dmsg)
                                        await cog_notifications.dispatch(client, 'oversized images', dmsg)
                                    else:
                                        dmsg = '{0.author.nick}({0.author.name})`({0.author.id})` posted a picture({1}x{2}) in #{0.channel.name} at {0.server.name}.'.format(message, i.get('width'),i.get('height'))
                                        print('({0.hour:02d}:{0.minute:02d})'.format(datetime.now())+dmsg)
                                        await cog_notifications.dispatch(client, 'oversized images', dmsg)
                                    break
                            except AttributeError:
                                print('({1.hour:02d}:{1.minute:02d}){0.author.name} posted weird embed in #{0.channel.name} at {0.server.name}.'.format(message, datetime.now()))
                                break
                if message.embeds:
                    for i in message.embeds:
                        if i.get('type') == 'image':
                            if(i.get('thumbnail').get('width')) and (i.get('thumbnail').get('height') > 128):
                                if i.get('thumbnail').get('width') > 400:
                                        if (i.get('thumbnail').get('height')*0.75) < 128:
                                            break
                                if message.author.nick is None:
                                    dmsg = '{0.author.name}`({0.author.id})` posted a picture({1}x{2}) in #{0.channel.name} at {0.server.name}.'.format(message, i.get('thumbnail').get('width'),i.get('thumbnail').get('height'))
                                    print('({0.hour:02d}:{0.minute:02d})'.format(datetime.now())+dmsg)
                                    await cog_notifications.dispatch(client, 'oversized images', dmsg)
                                else:
                                    dmsg = '{0.author.nick}({0.author.name})`({0.author.id})` posted a picture({1}x{2}) in #{0.channel.name} at {0.server.name}.'.format(message, i.get('thumbnail').get('width'),i.get('thumbnail').get('height'))
                                    print('({0.hour:02d}:{0.minute:02d})'.format(datetime.now())+dmsg)
                                    await cog_notifications.dispatch(client, 'oversized images', dmsg)
                                break
Ejemplo n.º 7
0
 def __init__(self, client):
     self.client = client
     self.searcher = Search(filter_id=56027)  # "everything" filter
Ejemplo n.º 8
0
class search(commands.Cog):
    def __init__(self, client):
        self.client = client
        self.searcher = Search(filter_id=56027)  # "everything" filter

    async def do_sfw_snark(self, ctx, tags):
        if 'grimdark' in tags and 'explicit' in tags:
            await ctx.channel.send("Absolutely not.")
        elif 'explicit' in tags or 'questionable' in tags or 'suggestive' in tags:
            if 'lyra' in tags:
                await ctx.channel.send(
                    "Hey, at least take me out to dinner first!")
            else:
                await ctx.channel.send(
                    "Ponies are NOT for sexual ||at least not in this channel||"
                )
        elif 'grimdark' in tags:
            await ctx.channel.send("I'd rather not see that")
        elif 'anthro' in tags:
            await ctx.channel.send("Get some better taste!")
        elif 'scootabuse' in tags:
            await ctx.channel.send("Imagine all the people")
        else:
            return False
        return True

    async def do_nsfw_snark(self, ctx, tags):
        if 'grimdark' in tags or 'anthro' in tags or 'scootabuse' in tags:
            await ctx.channel.send("<:ew:532536050350948376>")
            return True
        return False

    async def do_escape_paren_snark(self, ctx, tags):
        searchstring = ", ".join(tags)

        quoted = False
        escaped = False
        balance = 0
        for char in searchstring:
            if quoted:
                if char == "\"":
                    quoted = False
                continue
            elif char == "\"":
                quoted = True
                continue

            if escaped:
                escaped = False
                continue
            elif char == "\\":
                escaped = True
                continue

            if char == "(":
                balance += 1
            elif char == ")":
                balance -= 1

            if balance < 0:
                await ctx.channel.send("Very funny.")
                return True
        return False

    @commands.command()
    @commands.cooldown(1, 5, commands.BucketType.user)
    async def search(self, ctx, *, args="*"):
        """ Searches derpibooru for a given set of tags """
        tags = []
        if "_" in args:
            args = args.replace(" ", ",")
            args = args.replace("_", " ")
        tags = list(filter(None, [tag.strip() for tag in args.split(",")]))

        # meme joke
        youremom = ["you're mom", "youre mom", "you'remom", "youremom"]
        for mom in youremom:
            try:
                index = tags.index(mom)
                tags[index] = "gay"
            except ValueError:
                pass

        results = None

        # validate and choose content filtering tags
        if await self.do_escape_paren_snark(ctx, tags):
            return

        extratags = []
        if not ctx.channel.is_nsfw():
            if await self.do_sfw_snark(ctx, tags):
                return
            extratags = [
                "-explicit", "-questionable", "-suggestive", "-grimdark",
                "-anthro", "-scootabuse"
            ]
        else:  # in nsfw channel
            if await self.do_nsfw_snark(ctx, tags):
                return
            else:
                extratags = ["-grimdark", "-anthro", "-scootabuse"]

        for attempt in range(2):
            results = self.searcher.query(*extratags, "(" + ", ".join(tags) +
                                          ")").sort_by(sort.RANDOM).limit(1)

            if results is not None:
                posted = False  # ugly workaround because results doesn't say if there's anything inside unless you look
                for post in results:
                    await ctx.channel.send(post.url)
                    posted = True
                if posted:
                    break

            # first attempt didn't work, try splitting on spaces
            tags = " ".join(tags).split(" ")

        if not posted:
            await ctx.channel.send('No results for search "' + args +
                                   '". Too niche!')
Ejemplo n.º 9
0
class search(commands.Cog):
    def __init__(self, client):
        self.client = client
        self.searcher = Search(filter_id=56027)  # "everything" filter

    def get_derpi_embed(self, image_id, image_url, oembed):
        url = f'https://derpibooru.org/images/{image_id}'
        title = oembed["title"]
        if len(title) > 70:
            title = f'{title[:67]}...'
        embed = discord.Embed(title=title, url=url, color=6393795).set_author(
            name=oembed["author_name"]).set_image(url=image_url)
        return embed

    async def do_sfw_snark(self, ctx, tags):
        if 'grimdark' in tags and 'explicit' in tags:
            await ctx.channel.send("Absolutely not.")
        elif 'explicit' in tags or 'questionable' in tags or 'suggestive' in tags:
            if 'lyra' in tags:
                await ctx.channel.send(
                    "Hey, at least take me out to dinner first!")
            else:
                await ctx.channel.send(
                    "Ponies are NOT for sexual ||at least not in this channel||"
                )
        elif 'grimdark' in tags:
            await ctx.channel.send("I'd rather not see that")
        elif 'anthro' in tags:
            await ctx.channel.send("Get some better taste!")
        else:
            return False
        return True

    async def do_nsfw_snark(self, ctx, tags):
        if 'grimdark' in tags or 'anthro' in tags:
            await ctx.channel.send("<:ew:532536050350948376>")
            return True
        return False

    async def do_escape_paren_snark(self, ctx, tags):
        searchstring = ", ".join(tags)

        quoted = False
        escaped = False
        balance = 0
        for char in searchstring:
            if quoted:
                if char == "\"":
                    quoted = False
                continue
            elif char == "\"":
                quoted = True
                continue

            if escaped:
                escaped = False
                continue
            elif char == "\\":
                escaped = True
                continue

            if char == "(":
                balance += 1
            elif char == ")":
                balance -= 1

            if balance < 0:
                await ctx.channel.send("Very funny.")
                return True
        return False

    @commands.Cog.listener()
    async def on_message(self, message):
        if message.author.bot:
            return

        await asyncio.sleep(1)  # let embeds show up

        regex = re.compile("derpicdn.net")
        for embed in message.embeds:
            print("## embed found -- checking if image present and from derpi")
            thumb = embed.thumbnail
            if thumb == discord.Embed.Empty:
                thumb = embed.image
                if thumb == discord.Embed.Empty:
                    continue

            # direct links to derpicdn render fine and do not have titles
            if embed.title == discord.Embed.Empty:
                continue

            if regex.search(thumb.url):
                print(
                    "## found derpi image embed -- checking if fixup required")
                oembed_url = f'https://derpibooru.org/api/v1/json/oembed?url={thumb.url}'
                data = requests.get(oembed_url).json()
                # derpi embeds are only screwy if source author_url is None
                if data["author_url"] is not None:
                    continue

                print("## fixup required -- sending")
                image_id = data["derpibooru_id"]
                derpi_url = f'https://derpibooru.org/images/{image_id}'
                await message.channel.send(f"<{derpi_url}>",
                                           embed=self.get_derpi_embed(
                                               image_id, thumb.url, data))

    @commands.command(aliases=["rollzig"])
    @commands.cooldown(1, 5, commands.BucketType.user)
    async def rollzigger(self, ctx):
        """ Posts a random zigzog """
        await self.search(ctx, args="Zecora")

    @commands.command()
    @commands.cooldown(1, 5, commands.BucketType.user)
    async def search(self, ctx, *, args="*"):
        """ Searches derpibooru for a given set of tags """
        tags = []
        if "_" in args:
            args = args.replace(" ", ",")
            args = args.replace("_", " ")
        tags = list(filter(None, [tag.strip() for tag in args.split(",")]))

        # meme joke
        youremom = ["you're mom", "youre mom", "you'remom", "youremom"]
        for mom in youremom:
            try:
                index = tags.index(mom)
                tags[index] = "gay"
            except ValueError:
                pass

        results = None

        # validate and choose content filtering tags
        if await self.do_escape_paren_snark(ctx, tags):
            return

        extratags = []
        if (not ctx.channel.type == discord.ChannelType.private
                and not ctx.channel.type == discord.ChannelType.group
                and not ctx.channel.is_nsfw()):
            if await self.do_sfw_snark(ctx, tags):
                return
            extratags = [
                "-explicit", "-questionable", "-suggestive", "-grimdark",
                "-anthro"
            ]
        else:  # in nsfw channel
            if await self.do_nsfw_snark(ctx, tags):
                return
            else:
                extratags = ["-grimdark", "-anthro"]

        for attempt in range(2):
            results = self.searcher.query(*extratags, "(" + ", ".join(tags) +
                                          ")").sort_by(sort.RANDOM).limit(1)

            if results is not None:
                posted = False  # ugly workaround because results doesn't say if there's anything inside unless you look
                for post in results:
                    oembed_url = f'https://derpibooru.org/api/v1/json/oembed?url=https://derpibooru.org/{post.id}'
                    data = requests.get(oembed_url).json()
                    if data["author_url"] is not None:
                        await ctx.send(post.url)
                    else:
                        derpi_url = f'https://derpibooru.org/images/{post.id}'
                        await ctx.send(f'<{derpi_url}>',
                                       embed=self.get_derpi_embed(
                                           post.id, post.full, data))
                    posted = True
                if posted:
                    break

            # first attempt didn't work, try splitting on spaces
            tags = " ".join(tags).split(" ")

        if not posted:
            await ctx.channel.send('No results for search "' + args +
                                   '". Too niche!')
Ejemplo n.º 10
0
from derpibooru import Search, sort
import requests
from glob import glob

image_path = "data/images/"


def download(id, url):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        with open(image_path + "{}.png".format(id), 'wb') as f:
            for chunk in r:
                f.write(chunk)


query = "width.gt:1024, height.gt:1024, -animated"
print(query)

existing_files = [f[len(image_path):] for f in glob(image_path + "*")]

for image in Search().query(query).sort_by(sort.SCORE).limit(100000):
    try:
        if "{}.png".format(image.id) not in existing_files:
            download(image.id, image.full)
        else:
            print('.', end='', flush=True)
    except (IndexError, AttributeError):
        print("failed at image " + image.id)
Ejemplo n.º 11
0
#### END OF CONFIG. DO NOT TOUCH ANYTHING ELSE UNLESS YOU WANT TO CHANGE THE FUNCTIONALITY ####









print("Running!")
oldValues = []
newValues = []
try:
    for image in Search().key(key).filter(searchFilter).query(tags): #Initialising the initial value
        oldValues.append(image.url)
except:
    print("Error initialising picture search. Check your internet connection")
while True:
    time.sleep(60*delaytime)
    try:

        for image in Search().key(key).filter(searchFilter).query(tags): #Fetch all image urls on first page
            newValues.append(image.url)

            checkForNewImages = set(newValues[0:int((len(newValues)*oldPicTolerance))]).difference(set(oldValues)) #Checks for the difference in NEW pics uploaded, not old ones. Might cause some bugs if a huge number of pics are uploaded in the span of delaytime.
    except:
        print("Error connecting to the Derpibooru servers")
        newValues = []
        continue
Ejemplo n.º 12
0
    with open(os.path.join(THIS_DIR, 'past.json'), 'w') as f:
        f.write(json.dumps(pastPosts))

# Load past ids file
with open(os.path.join(THIS_DIR, 'past.json')) as d:
    pastPosts = json.load(d)

# Login to Twitter API
t = twitter.Api(consumer_key=config['twitter']['key'],
                consumer_secret=config['twitter']['secret'],
                access_token_key=config['twitter']['token'],
                access_token_secret=config['twitter']['tokenSecret'])

# Looks for our watched list posts
dt_delay = datetime.utcnow() - timedelta(minutes=30)
for post in Search().key(config['derpi']).query(
        'my:watched, %s' % dt_delay.strftime("%Y-%m-%d %H:%MZ")):
    # If the post is rendered and not already in our past ids
    if (post.is_rendered and post.id not in pastPosts):
        # Add hashtags
        hashtags = ['#Spoilers']
        eps = []

        for tag in post.tags:
            tag = tag.lower()

            if 'spoiler:s08' in tag:
                hashtags.append('#MLPSeason8')
                if 'spoiler:s08e' in tag:
                    eps.append(tag.replace('spoiler:', ''))

            if 'spoiler:s09' in tag: