Beispiel #1
0
async def buildMangaReplyWithAuthor(searchText,
                                    authorName,
                                    message,
                                    isExpanded,
                                    canEmbed,
                                    blockTracking=False):
    try:
        ani = await Anilist.getMangaWithAuthor(searchText, authorName)
        mal = None
        mu = None
        ap = None

        if ani:
            try:
                mal = await MAL.getMangaCloseToDescription(
                    searchText, ani['description'])
                ap = await AniP.getMangaURL(ani['title_english'], authorName)
            except Exception as e:
                print(e)
        else:
            ap = await AniP.getMangaURL(searchText, authorName)

        mu = await MU.getMangaWithAuthor(searchText, authorName)

        if ani:
            try:
                titleToAdd = ''
                if mal is not None:
                    titleToAdd = mal['title']
                else:
                    titleToAdd = ani['title_english']

                if not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Manga',
                                               message.author.id,
                                               message.server.id)
            except:
                traceback.print_exc()
                pass

            if not canEmbed:
                return CommentBuilder.buildMangaComment(
                    isExpanded, mal, ani, mu, ap)
            else:
                return CommentBuilder.buildMangaEmbed(isExpanded, mal, ani, mu,
                                                      ap)

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #2
0
def buildVisualNovelReply(searchText,
                          isExpanded,
                          baseComment,
                          blockTracking=False):
    """ Builds an VN reply from VNDB """
    try:
        vndb = VNDB()

        try:
            query = ('SELECT dbLinks'
                     '  FROM synonyms'
                     ' WHERE type = "VN"'
                     '   AND lower(name) = ?')
            sqlCur.execute(query, [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                if 'vndb' in synonym and synonym['vndb']:
                    synonym = synonym['vndb']

                if synonym:
                    result = vndb.getVisualNovelDetailsById(synonym)
                else:
                    result = None

        else:
            result = vndb.getVisualNovelDetails(searchText)

        vndb.close()

        if result:
            try:
                titleToAdd = result['title']

                subreddit = str(baseComment.subreddit).lower
                ignored_subreddits = ('nihilate', 'roboragi')
                if subreddit not in ignored_subreddits and not blockTracking:
                    DatabaseHandler.addRequest(
                        name=titleToAdd,
                        rType='VN',
                        requester=baseComment.author.name,
                        subreddit=baseComment.subreddit)
            except Exception:
                traceback.print_exc()
                pass

            return CommentBuilder.buildVisualNovelComment(isExpanded, result)
        else:
            print('No result found for ' + searchText)
            return None

    except Exception:
        traceback.print_exc()
        return None
def buildMangaReplyWithAuthor(searchText, authorName, message, isExpanded, blockTracking=False):
    try:        
        ani = Anilist.getMangaWithAuthor(searchText, authorName)
        mal = None
        mu = None
        ap = None
        
        if ani:
            mal = MAL.getMangaCloseToDescription(searchText, ani['description'])
            ap = AniP.getMangaURL(ani['title_english'], authorName)
        else:
            ap = AniP.getMangaURL(searchText, authorName)

        mu = MU.getMangaWithAuthor(searchText, authorName)

        if ani:
            try:
                titleToAdd = ''
                if mal is not None:
                    titleToAdd = mal['title']
                else:
                    titleToAdd = ani['title_english']
                
                if not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Manga', message.author.id, message.server.id)
            except:
                traceback.print_exc()
                pass
            
            return CommentBuilder.buildMangaComment(isExpanded, mal, ani, mu, ap)
    
    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #4
0
def buildMangaReplyWithAuthor(searchText, authorName, isExpanded, baseComment, blockTracking=False):
    try:        
        ani = Anilist.getMangaWithAuthor(searchText, authorName)
        mal = None
        mu = None
        ap = None
        
        if ani:
            mal = MAL.getMangaCloseToDescription(searchText, ani['description'])
            ap = AniP.getMangaURL(ani['title_english'], authorName)
        else:
            ap = AniP.getMangaURL(searchText, authorName)

        mu = MU.getMangaWithAuthor(searchText, authorName)

        if ani:
            try:
                titleToAdd = ''
                if mal is not None:
                    titleToAdd = mal['title']
                else:
                    titleToAdd = ani['title_english']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (str(baseComment.subreddit).lower is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Manga', baseComment.author.name, baseComment.subreddit)
            except:
                traceback.print_exc()
                pass
            
            return CommentBuilder.buildMangaComment(isExpanded, mal, ani, mu, ap)
    
    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #5
0
def buildVisualNovelReply(searchText,
                          isExpanded,
                          baseComment,
                          blockTracking=False):
    try:
        vndb = VNDB()

        try:
            sqlCur.execute(
                'SELECT dbLinks FROM synonyms WHERE type = "VN" and lower(name) = ?',
                [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                vndbsyn = None
                if 'vndb' in synonym and synonym['vndb']:
                    synonym = synonym['vndb']

                result = vndb.getVisualNovelDetailsById(
                    synonym) if synonym else None

        else:
            result = vndb.getVisualNovelDetails(searchText)

        vndb.close()

        if result:
            try:
                titleToAdd = result['title']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (
                        str(baseComment.subreddit).lower
                        is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'VN',
                                               baseComment.author.name,
                                               baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

            return CommentBuilder.buildVisualNovelComment(isExpanded, result)
        else:
            print('No result found for ' + searchText)
            return None

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #6
0
def buildMangaReply(searchText, isExpanded, baseComment):
    try:
        #Basic breakdown:
        #If Anilist finds something, use it to find the MAL version.
        #If hits either MAL or Ani, use it to find the MU version.
        #If it hits either, add it to the request-tracking DB.
        
        ani = Anilist.getMangaDetails(searchText)
        mal = None
        mu = None
        
        if not (ani is None):
            mal = MAL.getMangaDetails(ani['title_romaji'])

        else:
            mal = MAL.getMangaDetails(searchText)

            if not (mal is None):
                ani = Anilist.getMangaDetails(mal['title'])

        if (ani is not None) or (mal is not None):
            try:
                titleToAdd = ''
                if mal is not None:
                    titleToAdd = mal['title']
                    mu = MU.getMangaURL(mal['title'])
                else:
                    titleToAdd = ani['title_english']
                    mu = MU.getMangaURL(ani['title_romaji'])

                if (str(baseComment.subreddit).lower is not 'nihilate') and (str(baseComment.subreddit).lower is not 'roboragi'):
                    DatabaseHandler.addRequest(titleToAdd, 'Manga', baseComment.author.name, baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

            if ani is not None:
                if ani['adult'] is True:
                    print("NSFW ENTRY")
                    mal = None
                    ani = None
                    mu = None
            
            return CommentBuilder.buildMangaComment(isExpanded, mal, ani, mu)
    
    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #7
0
def buildMangaReplyWithAuthor(searchText,
                              authorName,
                              isExpanded,
                              baseComment,
                              blockTracking=False):
    try:
        ani = Anilist.getMangaWithAuthor(searchText, authorName)
        mal = None
        mu = None
        ap = None

        if ani:
            mal = MAL.getMangaCloseToDescription(searchText,
                                                 ani['description'])
            ap = AniP.getMangaURL(ani['title_english'], authorName)
        else:
            ap = AniP.getMangaURL(searchText, authorName)

        mu = MU.getMangaWithAuthor(searchText, authorName)

        if ani:
            try:
                titleToAdd = ''
                if mal is not None:
                    titleToAdd = mal['title']
                else:
                    titleToAdd = ani['title_english']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (
                        str(baseComment.subreddit).lower
                        is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Manga',
                                               baseComment.author.name,
                                               baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

            return CommentBuilder.buildMangaComment(isExpanded, mal, ani, mu,
                                                    ap)

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #8
0
def buildAnimeReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:
        mal = {
            'search_function': MAL.getAnimeDetails,
            'synonym_function': MAL.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        hb = {
            'search_function': Hummingbird.getAnimeDetails,
            'synonym_function': Hummingbird.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        ani = {
            'search_function': Anilist.getAnimeDetails,
            'synonym_function': Anilist.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        ap = {'search_function': AniP.getAnimeURL, 'result': None}
        adb = {'search_function': AniDB.getAnimeURL, 'result': None}

        try:
            sqlCur.execute(
                'SELECT dbLinks FROM synonyms WHERE type = "Anime" and lower(name) = ?',
                [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                malsyn = None
                if 'mal' in synonym and synonym['mal']:
                    malsyn = synonym['mal']

                hbsyn = None
                if 'hb' in synonym and synonym['hb']:
                    hbsyn = synonym['hb']

                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                apsyn = None
                if 'ap' in synonym and synonym['ap']:
                    apsyn = synonym['ap']

                adbsyn = None
                if 'adb' in synonym and synonym['adb']:
                    adbsyn = synonym['adb']

                mal['result'] = MAL.getAnimeDetails(
                    malsyn[0], malsyn[1]) if malsyn else None
                hb['result'] = Hummingbird.getAnimeDetailsById(
                    hbsyn) if hbsyn else None
                ani['result'] = Anilist.getAnimeDetailsById(
                    anisyn) if anisyn else None
                ap['result'] = AniP.getAnimeURLById(apsyn) if apsyn else None
                adb['result'] = AniDB.getAnimeURLById(
                    adbsyn) if adbsyn else None

        else:
            data_sources = [ani, hb, mal]
            #aux_sources = [ap, adb]
            aux_sources = [ap]

            synonyms = set([searchText])

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in synonyms:
                            if synonym in source['checked_synonyms']:
                                continue

                            source['result'] = source['search_function'](
                                synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        synonyms.update([
                            synonym.lower() for synonym in
                            source['synonym_function'](source['result'])
                        ])

            for source in aux_sources:
                for synonym in synonyms:
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

        if ani['result'] or hb['result'] or mal['result']:
            try:
                titleToAdd = ''
                if mal['result']:
                    titleToAdd = mal['result']['title']
                if hb['result']:
                    titleToAdd = hb['result']['title']
                if ani['result']:
                    titleToAdd = ani['result']['title_romaji']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (
                        str(baseComment.subreddit).lower
                        is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Anime',
                                               baseComment.author.name,
                                               baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

        return CommentBuilder.buildAnimeComment(isExpanded, mal['result'],
                                                hb['result'], ani['result'],
                                                ap['result'], adb['result'])

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #9
0
async def process_message(message, is_edit=False):
    #Anime/Manga requests that are found go into separate arrays
    animeArray = []
    mangaArray = []
    lnArray = []

    #Checks if bot has permissions to embed
    if message.channel.type != discord.ChannelType.private:
        canEmbed = message.channel.server.default_role.permissions.embed_links
    else:
        canEmbed = True
    if not canEmbed:
        botMember = Discord.getMemberFromID(Config.clientid, message.server)
        defaultroleperm = botMember.top_role.permissions
        canEmbed = defaultroleperm.embed_links

    isAdmin = message.author.top_role.permissions.administrator
    isServerMod = message.author.top_role.permissions.manage_server
    isOwner = message.author.id == ownerID

    if message.author.bot:
        return

    #ignores all "code" markup (i.e. anything between backticks)
    preCleanMessage = re.sub(r"\`(.*?)\`", "", message.clean_content)
    cleanMessage = re.sub(r'<:.+?:([0-9]{15,21})>', "", preCleanMessage)
    messageReply = ''

    if re.search('({!help.*?}|{{!help.*?}}|<!help.*?>|<<!help.*?>>)',
                 cleanMessage, re.S) is not None:
        try:
            localEm = CommentBuilder.buildHelpEmbed()
            await Discord.client.send_message(message.channel, embed=localEm)
            return
        except:
            return

    if re.search(
            '({!command.*?}|{{!command.*?}}|<!command.*?>|<<!command.*?>>)',
            cleanMessage, re.S) is not None:
        if 'toggleexpanded' in cleanMessage.lower() and (isAdmin
                                                         or isServerMod):
            try:
                allowedStatus = DatabaseHandler.toggleAllowExpanded(
                    message.server.id)
                print("Toggled allowExpanded for server {}".format(
                    message.server.id))
                if allowedStatus.lower() == 'true':
                    await Discord.client.send_message(
                        message.channel, "Expanded requests are now allowed.")
                else:
                    await Discord.client.send_message(
                        message.channel,
                        "Expanded requests are now disallowed.")
                return
            except Exception as e:
                print(e)
                return

        if 'addserver' in cleanMessage.lower() and (isOwner == True):
            try:
                DatabaseHandler.addServerToDatabase(message.server.id)
                await Discord.client.send_message(message.channel,
                                                  "Server has been added.")
                return
            except Exception as e:
                print(e)
                return

        else:
            print("command failed, user probably has insufficient rights")
            return

    sender = re.search('[@]([A-Za-z0-9 _-]+?)(>|}|$)', cleanMessage, re.S)
    mentionArray = message.raw_mentions
    if re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)',
                 cleanMessage, re.S) is not None and sender is not None:
        for mention in mentionArray:
            if not canEmbed:
                messageReply = CommentBuilder.buildStatsComment(
                    server=message.server, username=mention)
            else:
                localEm = CommentBuilder.buildStatsEmbed(server=message.server,
                                                         username=mention)
                await Discord.client.send_message(message.channel,
                                                  embed=localEm)
                return None
    if re.search('({!sstats}|{{!sstats}}|<!sstats>|<<!sstats>>)', cleanMessage,
                 re.S) is not None:
        if not canEmbed:
            messageReply = CommentBuilder.buildStatsComment(
                server=message.server)
        else:
            localEm = CommentBuilder.buildStatsEmbed(server=message.server)
            await Discord.client.send_message(message.channel, embed=localEm)
            return None
    elif re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)',
                   cleanMessage, re.S) is not None:
        if not canEmbed:
            messageReply = CommentBuilder.buildStatsComment()
        else:
            localEm = CommentBuilder.buildStatsEmbed()
            await Discord.client.send_message(message.channel, embed=localEm)
            return None
    else:

        #The basic algorithm here is:
        #If it's an expanded request, build a reply using the data in the braces, clear the arrays, add the reply to the relevant array and ignore everything else.
        #If it's a normal request, build a reply using the data in the braces, add the reply to the relevant array.

        #Counts the number of expanded results vs total results. If it's not just a single expanded result, they all get turned into normal requests.
        numOfRequest = 0
        numOfExpandedRequest = 0
        forceNormal = False
        expandedAllowed = DatabaseHandler.checkServerConfig(
            'allowexpanded', message.server.id)
        if expandedAllowed == False:
            forceNormal = True
        for match in re.finditer("\{{2}([^}]*)\}{2}|\<{2}([^>]*)\>{2}",
                                 cleanMessage, re.S):
            numOfRequest += 1
            numOfExpandedRequest += 1
            print("Request found: {}".format(match.group(0)))

        for match in re.finditer(
                "(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))|(?<=(?<!\<)\<)([^\<\>]*)(?=\>(?!\>))",
                cleanMessage, re.S):
            numOfRequest += 1
            print("Request found: {}".format(match.group(0)))

        if (numOfExpandedRequest >= 1) and (numOfRequest > 1):
            forceNormal = True

        #if numOfRequest != 0:
        #await Discord.client.send_typing(message.channel)
        #Expanded Anime
        for match in re.finditer("\{{2}([^}]*)\}{2}", cleanMessage, re.S):
            reply = ''
            if match.group(1) != '':
                if (forceNormal) or (str(message.channel).lower()
                                     in disableexpanded):
                    reply = await DiscordoragiSearch.buildAnimeReply(
                        match.group(1), message, False, canEmbed)
                else:
                    reply = await DiscordoragiSearch.buildAnimeReply(
                        match.group(1), message, True, canEmbed)

                if (reply is not None):
                    animeArray.append(reply)
            else:
                print("Empty request, ignoring")

        #Normal Anime
        for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))",
                                 cleanMessage, re.S):
            if match.group(1) != '':
                reply = await DiscordoragiSearch.buildAnimeReply(
                    match.group(1), message, False, canEmbed)

                if (reply is not None):
                    animeArray.append(reply)
                else:
                    print('Could not find anime')
            else:
                print("Empty request, ignoring")

        #Expanded Manga
        #NORMAL EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}(?!(:|\>))", cleanMessage,
                                 re.S):
            if match.group(1) != '':
                reply = ''

                if (forceNormal) or (str(message.channel).lower()
                                     in disableexpanded):
                    reply = await DiscordoragiSearch.buildMangaReply(
                        match.group(1), message, False, canEmbed)
                else:
                    reply = await DiscordoragiSearch.buildMangaReply(
                        match.group(1), message, True, canEmbed)

                if (reply is not None):
                    mangaArray.append(reply)
            else:
                print("Empty request, ignoring")

        #AUTHOR SEARCH EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}:\(([^)]+)\)", cleanMessage,
                                 re.S):
            if match.group(1) != '':
                reply = ''

                if (forceNormal) or (str(message.server).lower()
                                     in disableexpanded):
                    reply = await DiscordoragiSearch.buildMangaReplyWithAuthor(
                        match.group(1), match.group(2), message, False,
                        canEmbed)
                else:
                    reply = await DiscordoragiSearch.buildMangaReplyWithAuthor(
                        match.group(1), match.group(2), message, True,
                        canEmbed)

                if (reply is not None):
                    mangaArray.append(reply)
            else:
                print("Empty request, ignoring")

        #Normal Manga
        #NORMAL
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]+)\>(?!(:|\>))",
                                 cleanMessage, re.S):
            if match.group(1) != '':
                reply = await DiscordoragiSearch.buildMangaReply(
                    match.group(1), message, False, canEmbed)

                if (reply is not None):
                    mangaArray.append(reply)
            else:
                print("Empty request, ignoring")

        #AUTHOR SEARCH
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]*)\>:\(([^)]+)\)",
                                 cleanMessage, re.S):
            reply = await DiscordoragiSearch.buildMangaReplyWithAuthor(
                match.group(1), match.group(2), message, False, canEmbed)

            if (reply is not None):
                mangaArray.append(reply)

        #Expanded LN
        for match in re.finditer("\]{2}([^]]*)\[{2}", cleanMessage, re.S):
            if match.group(1) != '':
                reply = ''

                if (forceNormal) or (str(message.server).lower()
                                     in disableexpanded):
                    reply = await DiscordoragiSearch.buildLightNovelReply(
                        match.group(1), False, message, canEmbed)
                else:
                    reply = await DiscordoragiSearch.buildLightNovelReply(
                        match.group(1), True, message, canEmbed)

                if (reply is not None):
                    lnArray.append(reply)
            else:
                print("Empty request, ignoring")

        #Normal LN
        for match in re.finditer("(?<=(?<!\])\])([^\]\[]*)(?=\[(?!\[))",
                                 cleanMessage, re.S):
            if match.group(1) != '':
                reply = await DiscordoragiSearch.buildLightNovelReply(
                    match.group(1), False, message, canEmbed)

                if (reply is not None):
                    lnArray.append(reply)
            else:
                print("Empty request, ignoring")

        #Here is where we create the final reply to be posted

        #The final message reply. We add stuff to this progressively.
        postedAnimeTitles = []
        postedMangaTitles = []
        postedLNTitles = []

        messageReply = ''
        #Basically just to keep track of people posting the same title multiple times (e.g. {Nisekoi}{Nisekoi}{Nisekoi})
        postedAnimeTitles = []
        postedMangaTitles = []
        postedLNTitles = []
        #Adding all the anime to the final message. If there's manga too we split up all the paragraphs and indent them in Reddit markup by adding a '>', then recombine them
        for i, animeReply in enumerate(animeArray):
            if not (i is 0):
                messageReply += '\n\n'
            if not (animeReply['title'] in postedAnimeTitles):
                postedAnimeTitles.append(animeReply['title'])
                if not canEmbed:
                    messageReply += animeReply['comment']
                else:
                    messageReply = 'n/a'
        if mangaArray:
            messageReply += '\n\n'
        #Adding all the manga to the final message
        for i, mangaReply in enumerate(mangaArray):
            if not (i is 0):
                messageReply += '\n\n'
            if not (mangaReply['title'] in postedMangaTitles):
                postedMangaTitles.append(mangaReply['title'])
                if not canEmbed:
                    messageReply += mangaReply['comment']
                else:
                    messageReply = 'n/a'
        if lnArray:
            messageReply += '\n\n'
        #Adding all the manga to the final comment
        for i, lnReply in enumerate(lnArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (lnReply['title'] in postedLNTitles):
                postedLNTitles.append(lnReply['title'])
                if not canEmbed:
                    messageReply += lnReply['comment']
                else:
                    messageReply = 'N/A'
        #If there are more than 10 requests, shorten them all
        if not (messageReply is '') and (len(animeArray) + len(mangaArray) >=
                                         10):
            messageReply = re.sub(r"\^\((.*?)\)", "", messageReply, flags=re.M)
    #If there was actually something found, add the signature and post the message to Reddit. Then, add the message to the "already seen" database.
    if not (messageReply is ''):

        if is_edit:
            if not canEmbed:
                await Discord.client.send_message(message.channel,
                                                  messageReply)
            else:
                for i, animeReply in enumerate(animeArray):
                    await Discord.client.send_message(
                        message.channel, embed=animeReply['embed'])
                for i, mangaReply in enumerate(mangaArray):
                    await Discord.client.send_message(
                        message.channel, embed=mangaReply['embed'])
                for i, lnReply in enumerate(lnArray):
                    await Discord.client.send_message(message.channel,
                                                      embed=lnReply['embed'])
        else:
            try:
                print("Message created.\n")
                if not canEmbed:
                    await Discord.client.send_message(message.channel,
                                                      messageReply)
                else:
                    for i, animeReply in enumerate(animeArray):
                        await Discord.client.send_message(
                            message.channel, embed=animeReply['embed'])
                    for i, mangaReply in enumerate(mangaArray):
                        await Discord.client.send_message(
                            message.channel, embed=mangaReply['embed'])
                    for i, lnReply in enumerate(lnArray):
                        await Discord.client.send_message(
                            message.channel, embed=lnReply['embed'])
            except discord.errors.Forbidden:
                print('Request from banned channel: ' + str(message.channel) +
                      '\n')
            except Exception as e:
                print(e)
                traceback.print_exc()
            except:
                traceback.print_exc()
    else:
        try:
            if is_edit:
                return None
            else:
                DatabaseHandler.addMessage(message.id, message.author.id,
                                           message.server.id, False)
        except:
            traceback.print_exc()
Beispiel #10
0
def buildAnimeReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:
        kit = {
            'search_function': Kitsu.search_anime,
            'synonym_function': Kitsu.get_synonyms,
            'title_function': Kitsu.get_titles,
            'checked_synonyms': [],
            'result': None
        }
        ani = {
            'search_function': Anilist.getAnimeDetails,
            'synonym_function': Anilist.getSynonyms,
            'title_function': Anilist.getTitles,
            'checked_synonyms': [],
            'result': None
        }
        ap = {'search_function': AniP.getAnimeURL, 'result': None}

        try:
            sqlCur.execute(
                'SELECT dbLinks FROM synonyms WHERE type = "Anime" and lower(name) = ?',
                [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                kitsyn = None
                if 'kit' in synonym and synonym['kit']:
                    kitsyn = synonym['kit']

                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                apsyn = None
                if 'ap' in synonym and synonym['ap']:
                    apsyn = synonym['ap']

                kit['result'] = Kitsu.get_anime(kitsyn) if kitsyn else None
                ani['result'] = Anilist.getAnimeDetailsById(
                    anisyn) if anisyn else None
                ap['result'] = AniP.getAnimeURLById(apsyn) if apsyn else None

        else:
            data_sources = [ani, kit]
            aux_sources = [ap]

            synonyms = set([searchText])
            titles = set()

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in (titles | synonyms):
                            if synonym in source['checked_synonyms']:
                                continue

                            source['result'] = source['search_function'](
                                synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        synonyms.update([
                            synonym.lower() for synonym in
                            source['synonym_function'](source['result'])
                        ])
                        titles.update([
                            title.lower() for title in source['title_function']
                            (source['result'])
                        ])

            for source in aux_sources:
                for title in titles:
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

                if not source['result']:
                    for synonym in synonyms:
                        source['result'] = source['search_function'](synonym)

                        if source['result']:
                            break

        if ani['result'] or kit['result']:
            try:
                titleToAdd = ''
                if ani['result']:
                    if 'title_romaji' in ani['result']:
                        titleToAdd = ani['result']['title_romaji']
                elif kit['result']:
                    if 'title_romaji' in kit['result']:
                        titleToAdd = kit['result']['title_romaji']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (
                        str(baseComment.subreddit).lower
                        is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Anime',
                                               baseComment.author.name,
                                               baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

        if ani['result'] or kit['result']:
            return CommentBuilder.buildAnimeComment(isExpanded, ani['result'],
                                                    ap['result'],
                                                    kit['result'])
        else:
            print('No result found for ' + searchText)
            return None

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #11
0
def buildMangaReply(searchText, isExpanded, baseComment, blockTracking=False):
    """ Builds a manga reply from multiple sources """
    try:
        ani = {
            'search_function': Anilist.getMangaDetails,
            'title_function': Anilist.getTitles,
            'synonym_function': Anilist.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        kit = {
            'search_function': Kitsu.search_manga,
            'synonym_function': Kitsu.get_synonyms,
            'title_function': Kitsu.get_titles,
            'checked_synonyms': [],
            'result': None
        }
        mu = {'search_function': MU.getMangaURL, 'result': None}
        ap = {'search_function': AniP.getMangaURL, 'result': None}

        try:
            query = ('SELECT dbLinks'
                     '  FROM synonyms'
                     ' WHERE type = "Manga"'
                     '   AND lower(name) = ?')
            sqlCur.execute(query, [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                kitsyn = None
                if 'kit' in synonym and synonym['kit']:
                    kitsyn = synonym['kit']

                musyn = None
                if 'mu' in synonym and synonym['mu']:
                    musyn = synonym['mu']

                apsyn = None
                if 'ap' in synonym and synonym['ap']:
                    apsyn = synonym['ap']

                if anisyn:
                    ani['result'] = Anilist.getMangaDetailsById(anisyn)
                else:
                    ani['result'] = None
                kit['result'] = Kitsu.get_manga(kitsyn) if kitsyn else None
                mu['result'] = MU.getMangaURLById(musyn) if musyn else None
                ap['result'] = AniP.getMangaURLById(apsyn) if apsyn else None

        else:
            data_sources = [ani, kit]
            aux_sources = [mu, ap]

            synonyms = set([searchText])
            titles = set()

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for title in titles:
                            if title in source['checked_synonyms']:
                                break

                            if source['result']:
                                break

                            source['result'] = source['search_function'](title)
                            source['checked_synonyms'].append(title)

                            if source['result']:
                                break

                        for synonym in synonyms:
                            if synonym in source['checked_synonyms']:
                                break

                            if source['result']:
                                break

                            search_function = source['search_function']
                            source['result'] = search_function(synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        result = source['result']
                        synonym_function = source['synonym_function']
                        title_function = source['title_function']
                        synonyms.update(
                            [s.lower() for s in synonym_function(result)])
                        titles.update(
                            [t.lower() for t in title_function(result)])

            for source in aux_sources:
                for title in titles:
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

                if not source['result']:
                    for synonym in synonyms:
                        source['result'] = source['search_function'](synonym)

                        if source['result']:
                            break

        if ani['result'] or kit['result']:
            try:
                titleToAdd = ''
                if ani['result']:
                    try:
                        titleToAdd = ani['result']['title_romaji']
                    except Exception:
                        titleToAdd = ani['result']['title_english']
                elif kit['result']:
                    try:
                        titleToAdd = kit['result']['title_romaji']
                    except Exception:
                        titleToAdd = kit['result']['title_english']

                subreddit = str(baseComment.subreddit).lower
                ignored_subreddits = ('nihilate', 'roboragi')
                if subreddit not in ignored_subreddits and not blockTracking:
                    DatabaseHandler.addRequest(
                        name=titleToAdd,
                        rType='Manga',
                        requester=baseComment.author.name,
                        subreddit=baseComment.subreddit)
            except Exception:
                traceback.print_exc()
                pass

        if ani['result'] or kit['result']:
            return CommentBuilder.buildMangaComment(isExpanded=isExpanded,
                                                    ani=ani['result'],
                                                    mu=mu['result'],
                                                    ap=ap['result'],
                                                    kit=kit['result'])
        else:
            print('No result found for ' + searchText)
            return None

    except Exception:
        traceback.print_exc()
        return None
Beispiel #12
0
def process_comment(comment, is_edit=False):
    #Anime/Manga requests that are found go into separate arrays
    animeArray = []
    mangaArray = []
    lnArray = []

    #ignores all "code" markup (i.e. anything between backticks)
    comment.body = re.sub(r"\`(?s)(.*?)\`", "", comment.body)
    
    #This checks for requests. First up we check all known tags for the !stats request
    if re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)', comment.body, re.S) is not None:
        username = re.search('[uU]\/([A-Za-z0-9_-]+?)(>|}|$)', comment.body, re.S)
        subreddit = re.search('[rR]\/([A-Za-z0-9_]+?)(>|}|$)', comment.body, re.S)

        if username:
            commentReply = CommentBuilder.buildStatsComment(username=username.group(1))
        elif subreddit:
            commentReply = CommentBuilder.buildStatsComment(subreddit=subreddit.group(1))
        else:
            commentReply = CommentBuilder.buildStatsComment()
    else:
        
        #The basic algorithm here is:
        #If it's an expanded request, build a reply using the data in the braces, clear the arrays, add the reply to the relevant array and ignore everything else.
        #If it's a normal request, build a reply using the data in the braces, add the reply to the relevant array.

        #Counts the number of expanded results vs total results. If it's not just a single expanded result, they all get turned into normal requests.
        numOfRequest = 0
        numOfExpandedRequest = 0
        forceNormal = False

        for match in re.finditer("\{{2}([^}]*)\}{2}|\<{2}([^>]*)\>{2}", comment.body, re.S):
            numOfRequest += 1
            numOfExpandedRequest += 1
            
        for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))|(?<=(?<!\<)\<)([^\<\>]*)(?=\>(?!\>))", comment.body, re.S):
            numOfRequest += 1

        if (numOfExpandedRequest >= 1) and (numOfRequest > 1):
            forceNormal = True

        #Expanded Anime
        for match in re.finditer("\{{2}([^}]*)\}{2}", comment.body, re.S):
            reply = ''

            if (forceNormal) or (str(comment.subreddit).lower() in disableexpanded):
                reply = Search.buildAnimeReply(match.group(1), False, comment)
            else:
                reply = Search.buildAnimeReply(match.group(1), True, comment)                    

            if (reply is not None):
                animeArray.append(reply)

        #Normal Anime  
        for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))", comment.body, re.S):
            reply = Search.buildAnimeReply(match.group(1), False, comment)
            
            if (reply is not None):
                animeArray.append(reply)

        #Expanded Manga
        #NORMAL EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}(?!(:|\>))", comment.body, re.S):
            reply = ''
            
            if (forceNormal) or (str(comment.subreddit).lower() in disableexpanded):
                reply = Search.buildMangaReply(match.group(1), False, comment)
            else:
                reply = Search.buildMangaReply(match.group(1), True, comment)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}:\(([^)]+)\)", comment.body, re.S):
            reply = ''
            
            if (forceNormal) or (str(comment.subreddit).lower() in disableexpanded):
                reply = Search.buildMangaReplyWithAuthor(match.group(1), match.group(2), False, comment)
            else:
                reply = Search.buildMangaReplyWithAuthor(match.group(1), match.group(2), True, comment)

            if (reply is not None):
                mangaArray.append(reply)

        #Normal Manga
        #NORMAL
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]+)\>(?!(:|\>))", comment.body, re.S):
            reply = Search.buildMangaReply(match.group(1), False, comment)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]*)\>:\(([^)]+)\)", comment.body, re.S):
            reply = Search.buildMangaReplyWithAuthor(match.group(1), match.group(2), False, comment)

            if (reply is not None):
                mangaArray.append(reply)

        #Expanded LN
        for match in re.finditer("\]{2}([^]]*)\[{2}", comment.body, re.S):
            reply = ''

            if (forceNormal) or (str(comment.subreddit).lower() in disableexpanded):
                reply = Search.buildLightNovelReply(match.group(1), False, comment)
            else:
                reply = Search.buildLightNovelReply(match.group(1), True, comment)                    

            if (reply is not None):
                lnArray.append(reply)

        #Normal LN  
        for match in re.finditer("(?<=(?<!\])\])([^\]\[]*)(?=\[(?!\[))", comment.body, re.S):
            reply = Search.buildLightNovelReply(match.group(1), False, comment)
            
            if (reply is not None):
                lnArray.append(reply)
            
        #Here is where we create the final reply to be posted

        #The final comment reply. We add stuff to this progressively.
        commentReply = ''

        #Basically just to keep track of people posting the same title multiple times (e.g. {Nisekoi}{Nisekoi}{Nisekoi})
        postedAnimeTitles = []
        postedMangaTitles = []
        postedLNTitles = []

        #Adding all the anime to the final comment. If there's manga too we split up all the paragraphs and indent them in Reddit markup by adding a '>', then recombine them
        for i, animeReply in enumerate(animeArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (animeReply['title'] in postedAnimeTitles):
                postedAnimeTitles.append(animeReply['title'])
                commentReply += animeReply['comment']
            

        if mangaArray:
            commentReply += '\n\n'

        #Adding all the manga to the final comment
        for i, mangaReply in enumerate(mangaArray):
            if not (i is 0):
                commentReply += '\n\n'
            
            if not (mangaReply['title'] in postedMangaTitles):
                postedMangaTitles.append(mangaReply['title'])
                commentReply += mangaReply['comment']

        if lnArray:
            commentReply += '\n\n'

        #Adding all the manga to the final comment
        for i, lnReply in enumerate(lnArray):
            if not (i is 0):
                commentReply += '\n\n'
            
            if not (lnReply['title'] in postedLNTitles):
                postedLNTitles.append(lnReply['title'])
                commentReply += lnReply['comment']

        #If there are more than 10 requests, shorten them all 
        if not (commentReply is '') and (len(animeArray) + len(mangaArray)+ len(lnArray) >= 10):
            commentReply = re.sub(r"\^\((.*?)\)", "", commentReply, flags=re.M)

    #If there was actually something found, add the signature and post the comment to Reddit. Then, add the comment to the "already seen" database.
    if commentReply is not '':
        '''if (comment.author.name == 'treborabc'):
            commentReply = '[No.](https://www.reddit.com/r/anime_irl/comments/4sba1n/anime_irl/d58xkha)'''
        
        commentReply += Config.getSignature(comment.permalink)

        commentReply += Reference.get_bling(comment.author.name)

        if is_edit:
            return commentReply
        else:
            try:
                comment.reply(commentReply)
                print("Comment made.\n")
            except praw.errors.Forbidden:
                print('Request from banned subreddit: ' + str(comment.subreddit) + '\n')
            except Exception:
                traceback.print_exc()

            try:
                DatabaseHandler.addComment(comment.id, comment.author.name, comment.subreddit, True)
            except:
                traceback.print_exc()
    else:
        try:
            if is_edit:
                return None
            else:
                DatabaseHandler.addComment(comment.id, comment.author.name, comment.subreddit, False)
        except:
            traceback.print_exc()
Beispiel #13
0
def buildAnimeReply(searchText, isExpanded, baseComment):
    try:
        #Basic breakdown:
        #If Anilist finds something, use it to find the HB version.
        #If we can't find it, try with HB and use it to try and "refind" Anilist
        #If we hit HB, we don't need to look for MAL, since we can get the MAL ID from within HB. If we don't hit HB, find MAL on its own.
        #If, at the end, we have something from Anilist, get the full set of Anilist data
        #If it hits anything, add it to the request-tracking DB.
        
        ani = Anilist.getAnimeDetails(searchText)
        hb = None
        mal = None
        
        if (ani is not None):
            hb = Hummingbird.getAnimeDetails(ani['title_romaji'])

            if (hb is None):
                for synonym in ani['synonyms']:
                    hb = Hummingbird.getAnimeDetails(synonym)
                    if hb is not None:
                        break
                hb = Hummingbird.getAnimeDetails(ani['title_english'])
        else:
            hb = Hummingbird.getAnimeDetails(searchText)
            if (hb is not None):
               ani = Anilist.getAnimeDetails(hb['title'])

        if (hb is None):
            mal = MAL.getAnimeDetails(searchText)
            if (mal is not None):
                hb = Hummingbird.getAnimeDetails(mal['title'])
                if (hb is None):
                    hb = Hummingbird.getAnimeDetails(mal['english'])

                if (ani is None):
                    ani = Anilist.getAnimeDetails(mal['title'])
                    if (ani is None):
                        ani = Anilist.getAnimeDetails(mal['english'])

        try:
            if ani is not None:
                aniFull = Anilist.getFullAnimeDetails(ani['id'])
                if aniFull is not None:
                    ani = aniFull
        except:
            pass

        if (ani is not None) or (hb is not None) or (mal is not None):
            try:
                titleToAdd = ''
                if ani is None:
                    titleToAdd = hb['title']
                elif hb is not None:
                    titleToAdd = ani['title_romaji']
                else:
                    titleToAdd = mal['title']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (str(baseComment.subreddit).lower is not 'roboragi'):
                    DatabaseHandler.addRequest(titleToAdd, 'Anime', baseComment.author.name, baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

            if ani is not None:
                if ani['adult'] is True:
                    print("NSFW ENTRY")
                    mal = None
                    hb = None
                    ani = None
            
            return CommentBuilder.buildAnimeComment(isExpanded, mal, hb, ani)

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #14
0
def buildAnimeReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:

        mal = None
        hb = None
        ani = None
        ap = None
        
        try:
            sqlCur.execute('SELECT dbLinks FROM synonyms WHERE type = "Anime" and lower(name) = ?', [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if (synonym['mal']):
                mal = MAL.getAnimeDetails(synonym['mal'])
            if (synonym['hb']):
                hb = Hummingbird.getAnimeDetails(synonym['hb'])
            if (synonym['ani']):
                ani = Anilist.getAnimeDetails(synonym['ani'])
            if (synonym['ap']):
                ap = AniP.getAnimeURL(synonym['ap'])
        else:
            #Basic breakdown:
            #If Anilist finds something, use it to find the HB version.
            #If we can't find it, try with HB and use it to try and "refind" Anilist
            #If we hit HB, we don't need to look for MAL, since we can get the MAL ID from within HB. If we don't hit HB, find MAL on its own.
            #If, at the end, we have something from Anilist, get the full set of Anilist data
            #If it hits anything, add it to the request-tracking DB.
            
            ani = Anilist.getAnimeDetails(searchText)
            
            if (ani is not None):
                hb = Hummingbird.getAnimeDetails(ani['title_romaji'])

                if (hb is None):
                    for synonym in ani['synonyms']:
                        hb = Hummingbird.getAnimeDetails(synonym)
                        if hb is not None:
                            break
                    hb = Hummingbird.getAnimeDetails(ani['title_english'])
            else:
                hb = Hummingbird.getAnimeDetails(searchText)
                if (hb is not None):
                   ani = Anilist.getAnimeDetails(hb['title'])

            #Doing MAL stuff
            if not mal:
                if hb:
                    mal = MAL.getAnimeDetails(hb['title'])

                    if not mal and hb['alternate_title']:
                        if (hb['alternate_title']):
                            mal = MAL.getAnimeDetails(hb['alternate_title'])
                        
                if ani and not mal:
                    mal = MAL.getAnimeDetails(ani['title_romaji'])

                    if not mal:
                        mal = MAL.getAnimeDetails(ani['title_english'])

                    if not mal and ani['synonyms']:
                        for synonym in ani['synonyms']:
                            if mal:
                                break
                            mal = MAL.getAnimeDetails(synonym)

                if not mal:
                    mal = MAL.getAnimeDetails(searchText)

                if mal and not hb:
                    hb = Hummingbird.getAnimeDetails(mal['title'])
                    if not hb:
                        hb = Hummingbird.getAnimeDetails(mal['english'])

                if mal and not ani:
                    ani = Anilist.getAnimeDetails(mal['title'])
                    if not ani:
                        ani = Anilist.getAnimeDetails(mal['english'])

        #----- Finally... -----#
        try:
            if ani is not None:
                aniFull = Anilist.getFullAnimeDetails(ani['id'])
                if aniFull is not None:
                    ani = aniFull
        except:
            pass

        if (ani is not None) or (hb is not None) or (mal is not None):
            try:
                titleToAdd = ''
                if mal:
                    titleToAdd = mal['title']
                if hb:
                    titleToAdd = hb['title']
                if ani:
                    titleToAdd = ani['title_romaji']

                #Do Anime-Planet stuff
                if mal and not ap:
                    if mal['title'] and not ap:
                        ap = AniP.getAnimeURL(mal['title'])
                    if mal['english'] and not ap:
                        ap = AniP.getAnimeURL(mal['english'])
                    if mal['synonyms'] and not ap:
                        for synonym in mal['synonyms']:
                            if ap:
                                break
                            ap = AniP.getAnimeURL(synonym)

                if hb and not ap:
                    if hb['title'] and not ap:
                        ap = AniP.getAnimeURL(hb['title'])
                    if hb['alternate_title'] and not ap:
                        ap = AniP.getAnimeURL(hb['alternate_title'])
                
                if ani and not ap:
                    if ani['title_english'] and not ap:
                        ap = AniP.getAnimeURL(ani['title_english'])
                    if ani['title_romaji'] and not ap:
                        ap = AniP.getAnimeURL(ani['title_romaji'])
                    if ani['synonyms'] and not ap:
                        for synonym in ani['synonyms']:
                            if ap:
                                break
                            ap = AniP.getAnimeURL(synonym)

                if (str(baseComment.subreddit).lower is not 'nihilate') and (str(baseComment.subreddit).lower is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Anime', baseComment.author.name, baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

        if ani is not None:
            if ani['adult'] is True:
                print("NSFW ENTRY")
                mal = None
                hb = None
                ani = None
                ap = None
        
        return CommentBuilder.buildAnimeComment(isExpanded, mal, hb, ani, ap)

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #15
0
async def process_message(message, is_edit=False):
    #Anime/Manga requests that are found go into separate arrays
    animeArray = []
    mangaArray = []
    lnArray = []

    #ignores all "code" markup (i.e. anything between backticks)
    cleanMessage = re.sub(r"\`(?s)(.*?)\`", "", message.clean_content)

    sender = re.search('[@]([A-Za-z0-9_-]+?)(>|}|$)', cleanMessage, re.S)
    
    if re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)', cleanMessage, re.S) is not None and sender is not None:
        messageReply = CommentBuilder.buildStatsComment(username=sender.group(1))
    if re.search('({!sstats.*?}|{{!sstats.*?}}|<!sstats.*?>|<<!sstats.*?>>)', cleanMessage, re.S) is not None:
        server = re.search('([A-Za-z0-9_]+?)(>|}|$)', cleanMessage, re.S)
        messageReply = CommentBuilder.buildStatsComment(server=server.group(1))
    elif re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)', cleanMessage, re.S) is not None:
        messageReply = CommentBuilder.buildStatsComment()
    else:
        
        #The basic algorithm here is:
        #If it's an expanded request, build a reply using the data in the braces, clear the arrays, add the reply to the relevant array and ignore everything else.
        #If it's a normal request, build a reply using the data in the braces, add the reply to the relevant array.
        
        #Counts the number of expanded results vs total results. If it's not just a single expanded result, they all get turned into normal requests.
        numOfRequest = 0
        numOfExpandedRequest = 0
        forceNormal = False
        for match in re.finditer("\{{2}([^}]*)\}{2}|\<{2}([^>]*)\>{2}", cleanMessage, re.S):
            numOfRequest += 1
            numOfExpandedRequest += 1

        for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))|(?<=(?<!\<)\<)([^\<\>]*)(?=\>(?!\>))", cleanMessage, re.S):
            numOfRequest += 1

        if (numOfExpandedRequest >= 1) and (numOfRequest > 1):
            forceNormal = True

        #Expanded Anime
        for match in re.finditer("\{{2}([^}]*)\}{2}", cleanMessage, re.S):
            reply = ''
            if (forceNormal) or (str(message.channel).lower() in disableexpanded):
                reply = DiscordoragiSearch.buildAnimeReply(match.group(1), message, False)
            else:
                reply = DiscordoragiSearch.buildAnimeReply(match.group(1), message, True)

            if (reply is not None):
                animeArray.append(reply)

        #Normal Anime
        for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))", cleanMessage, re.S):
            reply = DiscordoragiSearch.buildAnimeReply(match.group(1), message, False)

            if (reply is not None):
                animeArray.append(reply)

        #Expanded Manga
        #NORMAL EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}(?!(:|\>))", cleanMessage, re.S):
            reply = ''

            if (forceNormal) or (str(message.channel).lower() in disableexpanded):
                reply = DiscordoragiSearch.buildMangaReply(match.group(1), message, False)
            else:
                reply = DiscordoragiSearch.buildMangaReply(match.group(1), message, True)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}:\(([^)]+)\)", cleanMessage, re.S):
            reply = ''

            if (forceNormal) or (str(message.server).lower() in disableexpanded):
                reply = DiscordoragiSearch.buildMangaReplyWithAuthor(match.group(1), match.group(2), message, False)
            else:
                reply = DiscordoragiSearch.buildMangaReplyWithAuthor(match.group(1), match.group(2), message, True)

            if (reply is not None):
                mangaArray.append(reply)

        #Normal Manga
        #NORMAL
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]+)\>(?!(:|\>))", cleanMessage, re.S):
            reply = DiscordoragiSearch.buildMangaReply(match.group(1), message, False)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]*)\>:\(([^)]+)\)", cleanMessage, re.S):
            reply = DiscordoragiSearch.buildMangaReplyWithAuthor(match.group(1), match.group(2), message, False)

            if (reply is not None):
                mangaArray.append(reply)

        #Expanded LN
        for match in re.finditer("\]{2}([^]]*)\[{2}", cleanMessage, re.S):
            reply = ''

            if (forceNormal) or (str(message.server).lower() in disableexpanded):
                reply = DiscordoragiSearch.buildLightNovelReply(match.group(1), False, message)
            else:
                reply = DiscordoragiSearch.buildLightNovelReply(match.group(1), True, message)                    

            if (reply is not None):
                lnArray.append(reply)

        #Normal LN  
        for match in re.finditer("(?<=(?<!\])\])([^\]\[]*)(?=\[(?!\[))", cleanMessage, re.S):
            reply = DiscordoragiSearch.buildLightNovelReply(match.group(1), False, message)
            
            if (reply is not None):
                lnArray.append(reply)

        #Here is where we create the final reply to be posted

        #The final message reply. We add stuff to this progressively.
        messageReply = ''

        #Basically just to keep track of people posting the same title multiple times (e.g. {Nisekoi}{Nisekoi}{Nisekoi})
        postedAnimeTitles = []
        postedMangaTitles = []
        postedLNTitles = []

        #Adding all the anime to the final message. If there's manga too we split up all the paragraphs and indent them in Reddit markup by adding a '>', then recombine them
        for i, animeReply in enumerate(animeArray):
            if not (i is 0):
                messageReply += '\n\n'

            if not (animeReply['title'] in postedAnimeTitles):
                postedAnimeTitles.append(animeReply['title'])
                messageReply += animeReply['comment']


        if mangaArray:
            messageReply += '\n\n'

        #Adding all the manga to the final message
        for i, mangaReply in enumerate(mangaArray):
            if not (i is 0):
                messageReply += '\n\n'

            if not (mangaReply['title'] in postedMangaTitles):
                postedMangaTitles.append(mangaReply['title'])
                messageReply += mangaReply['comment']

        if lnArray:
            messageReply += '\n\n'

        #Adding all the manga to the final comment
        for i, lnReply in enumerate(lnArray):
            if not (i is 0):
                commentReply += '\n\n'
            
            if not (lnReply['title'] in postedLNTitles):
                postedLNTitles.append(lnReply['title'])
                messageReply += lnReply['comment']

        #If there are more than 10 requests, shorten them all
        if not (messageReply is '') and (len(animeArray) + len(mangaArray) >= 10):
            messageReply = re.sub(r"\^\((.*?)\)", "", messageReply, flags=re.M)

    #If there was actually something found, add the signature and post the message to Reddit. Then, add the message to the "already seen" database.
    if not (messageReply is ''):
        messageReply += Config.getSignature()

        if is_edit:
            await Discord.client.send_message(message.channel, messageReply)
        else:
            try:
                print("Message created.\n")
                await Discord.client.send_message(message.channel, messageReply)
            except discord.errors.Forbidden:
                print('Request from banned channel: ' + str(message.channel) + '\n')
            except Exception:
                traceback.print_exc()
            
            try:
                DatabaseHandler.addMessage(message.id, message.author.id, message.server.id, True)
            except:
                traceback.print_exc()
    else:
        try:
            if is_edit:
                return None
            else:
                DatabaseHandler.addMessage(message.id, message.author.id, message.server.id, False)
        except:
            traceback.print_exc()
Beispiel #16
0
def buildAnimeReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:

        mal = {'search_function': MAL.getAnimeDetails,
                'synonym_function': MAL.getSynonyms,
                'checked_synonyms': [],
                'result': None}
        hb = {'search_function': Hummingbird.getAnimeDetails,
                'synonym_function': Hummingbird.getSynonyms,
                'checked_synonyms': [],
                'result': None}
        ani = {'search_function': Anilist.getAnimeDetails,
                'synonym_function': Anilist.getSynonyms,
                'checked_synonyms': [],
                'result': None}
        ap = {'search_function': AniP.getAnimeURL,
                'result': None}
        adb = {'search_function': AniDB.getAnimeURL,
                'result': None}
        
        try:
            sqlCur.execute('SELECT dbLinks FROM synonyms WHERE type = "Anime" and lower(name) = ?', [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                malsyn = None
                if 'mal' in synonym and synonym['mal']:
                    malsyn = synonym['mal']

                hbsyn = None
                if 'hb' in synonym and synonym['hb']:
                    hbsyn = synonym['hb']

                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                apsyn = None
                if 'ap' in synonym and synonym['ap']:
                    apsyn = synonym['ap']

                adbsyn = None
                if 'adb' in synonym and synonym['adb']:
                    adbsyn = synonym['adb']

                mal['result'] = MAL.getAnimeDetails(malsyn[0],malsyn[1]) if malsyn else None
                hb['result'] = Hummingbird.getAnimeDetailsById(hbsyn) if hbsyn else None
                ani['result'] = Anilist.getAnimeDetailsById(anisyn) if anisyn else None
                ap['result'] = AniP.getAnimeURLById(apsyn) if apsyn else None
                adb['result'] = AniDB.getAnimeURLById(adbsyn) if adbsyn else None
                
        else:
            data_sources = [ani, hb, mal]
            aux_sources = [ap, adb]

            synonyms = set([searchText])

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in synonyms:
                            if synonym in source['checked_synonyms']:
                                continue

                            source['result'] = source['search_function'](synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        synonyms.update([synonym.lower() for synonym in source['synonym_function'](source['result'])])

            for source in aux_sources:
                for synonym in synonyms:     
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

        if ani['result'] or hb['result'] or mal['result']:
            try:
                titleToAdd = ''
                if mal['result']:
                    titleToAdd = mal['result']['title']
                if hb['result']:
                    titleToAdd = hb['result']['title']
                if ani['result']:
                    titleToAdd = ani['result']['title_romaji']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (str(baseComment.subreddit).lower is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Anime', baseComment.author.name, baseComment.subreddit)
            except:
                traceback.print_exc()
                pass
        
        return CommentBuilder.buildAnimeComment(isExpanded, mal['result'], hb['result'], ani['result'], ap['result'], adb['result'])

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #17
0
def start():
    print('Starting comment stream:')

    #This opens a constant stream of comments. It will loop until there's a major error (usually this means the Reddit access token needs refreshing)
    comment_stream = praw.helpers.comment_stream(reddit, subredditlist, limit=250, verbosity=0)

    for comment in comment_stream:

        #Is the comment valid (i.e. it's not made by Roboragi and I haven't seen it already). If no, try to add it to the "already seen pile" and skip to the next comment. If yes, keep going.
        if not (Search.isValidComment(comment, reddit)):
            try:
                if not (DatabaseHandler.commentExists(comment.id)):
                    DatabaseHandler.addComment(comment.id, comment.author.name, comment.subreddit, False)
            except:
                pass
            continue

        #Anime/Manga requests that are found go into separate arrays
        animeArray = []
        mangaArray = []

        #The "hasExpandedRequest" variable puts a stop on any other requests (since you can only have one expanded request in a comment)
        hasExpandedRequest = False

        #ignores all "code" markup (i.e. anything between backticks)
        comment.body = re.sub(r"\`(?s)(.*?)\`", "", comment.body)
        
        #This checks for requests. First up we check all known tags for the !stats request
        # Assumes tag begins and ends with a whitespace OR at the string beginning/end
        if re.search('(^|\s)({!stats}|{{!stats}}|<!stats>|<<!stats>>)($|\s|.)', comment.body, re.S) is not None:
            commentReply = CommentBuilder.buildStatsComment(comment.subreddit)
        else:

            #The basic algorithm here is:
            #If it's an expanded request, build a reply using the data in the braces, clear the arrays, add the reply to the relevant array and ignore everything else.
            #If it's a normal request, build a reply using the data in the braces, add the reply to the relevant array.

            #Expanded Anime
            for match in re.finditer("\{{2}([^}]*)\}{2}", comment.body, re.S):
                if (str(comment.subreddit).lower() not in disableexpanded):
                    if hasExpandedRequest:
                        break
                    reply = Search.buildAnimeReply(match.group(1), True, comment)

                    if not (reply is None):
                        hasExpandedRequest = True
                        animeArray = [reply]
                        mangaArray = []
                else:
                    if hasExpandedRequest:
                        break
                    reply = Search.buildAnimeReply(match.group(1), False, comment)

                    if (reply is not None) and (len(animeArray) + len(mangaArray) < 10):
                        animeArray.append(reply)

            #Normal Anime  
            for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))", comment.body, re.S):
                if hasExpandedRequest:
                    break
                reply = Search.buildAnimeReply(match.group(1), False, comment)

                if (reply is not None) and (len(animeArray) + len(mangaArray) < 10):
                    animeArray.append(reply)

            #Expanded Manga
            for match in re.finditer("\<{2}([^>]*)\>{2}", comment.body, re.S):
                if (str(comment.subreddit).lower() not in disableexpanded):
                    if hasExpandedRequest:
                        break;
                    reply = Search.buildMangaReply(match.group(1), True, comment)

                    if not (reply is None):
                        hasExpandedRequest = True
                        animeArray = []
                        mangaArray = [reply]
                else:
                    if hasExpandedRequest:
                        break
                    reply = Search.buildMangaReply(match.group(1), False, comment)

                    if (reply is not None) and (len(animeArray) + len(mangaArray) < 10):
                        mangaArray.append(reply)

            #Normal Manga
            for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]*)(?=\>(?!\>))", comment.body, re.S):
                if hasExpandedRequest:
                    break
                reply = Search.buildMangaReply(match.group(1), False, comment)

                if (reply is not None) and (len(animeArray) + len(mangaArray) < 10):
                    mangaArray.append(reply)

                
            #Here is where we create the final reply to be posted

            #The final comment reply. We add stuff to this progressively.
            commentReply = ''

            #If we have anime AND manga in one reply we format stuff a little differently
            multipleTypes = False

            #Basically just to keep track of people posting the same title multiple times (e.g. {Nisekoi}{Nisekoi}{Nisekoi})
            postedAnimeTitles = []
            postedMangaTitles = []
            
            if (len(animeArray) > 0) and (len(mangaArray) > 0):
                multipleTypes = True
                commentReply += '**Anime**\n\n'

            #Adding all the anime to the final comment. If there's manga too we split up all the paragraphs and indent them in Reddit markup by adding a '>', then recombine them
            for i, animeReply in enumerate(animeArray):
                if not (i is 0):
                    commentReply += '\n\n'
                    
                if multipleTypes:
                    splitSections = re.split('\s{2,}',animeReply['comment'])
                    newSections = []
                    for section in splitSections:
                        newSections.append('>' + section)
                    animeReply['comment'] = '\n\n'.join(newSections)

                if not (animeReply['title'] in postedAnimeTitles):
                    postedAnimeTitles.append(animeReply['title'])
                    commentReply += animeReply['comment']
                

            if multipleTypes:
                commentReply += '\n\n**Manga**\n\n'

            #Adding all the manga to the final comment
            for i, mangaReply in enumerate(mangaArray):
                if not (i is 0):
                    commentReply += '\n\n'

                if multipleTypes:
                    splitSections = re.split('\s{2,}',mangaReply['comment'])
                    newSections = []
                    for section in splitSections:
                        newSections.append('>' + section)
                    mangaReply['comment'] = '\n\n'.join(newSections)
                
                if not (mangaReply['title'] in postedMangaTitles):
                    postedMangaTitles.append(mangaReply['title'])
                    commentReply += mangaReply['comment']

        #If there was actually something found, add the signature and post the comment to Reddit. Then, add the comment to the "already seen" database.
        if not (commentReply is ''):
            commentReply += '\n\n---\n\n [^How ^to ^use](http://www.reddit.com/r/Roboragi/wiki/index#wiki_how_do_i_use_it.3F) ^| ^[FAQ](http://www.reddit.com/r/Roboragi/wiki/index) ^| ^[Subreddit](http://www.reddit.com/r/Roboragi/) ^| ^[Issue/mistake?](http://www.reddit.com/r/Roboragi/submit?selftext=true&title=[ISSUE]&text=' + comment.permalink + ') ^| ^[Source](https://github.com/Nihilate/Roboragi)'

            try:
                comment.reply(commentReply)
                print("Comment made.\n")

                try:
                    DatabaseHandler.addComment(comment.id, comment.author.name, comment.subreddit, True)
                except:
                    traceback.print_exc()
            except:
                traceback.print_exc()
        else:
            try:
                DatabaseHandler.addComment(comment.id, comment.author.name, comment.subreddit, False)
            except:
                traceback.print_exc()
Beispiel #18
0
async def process_message(message, is_edit=False):
    #Anime/Manga requests that are found go into separate arrays
    animeArray = []
    mangaArray = []
    lnArray = []

    #ignores all "code" markup (i.e. anything between backticks)
    cleanMessage = re.sub(r"\`(?s)(.*?)\`", "", message.clean_content)

    sender = re.search('[@]([A-Za-z0-9_-]+?)(>|}|$)', cleanMessage, re.S)

    if re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)',
                 cleanMessage, re.S) is not None and sender is not None:
        messageReply = CommentBuilder.buildStatsComment(
            username=sender.group(1))
    if re.search('({!sstats.*?}|{{!sstats.*?}}|<!sstats.*?>|<<!sstats.*?>>)',
                 cleanMessage, re.S) is not None:
        server = re.search('([A-Za-z0-9_]+?)(>|}|$)', cleanMessage, re.S)
        messageReply = CommentBuilder.buildStatsComment(server=server.group(1))
    elif re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)',
                   cleanMessage, re.S) is not None:
        messageReply = CommentBuilder.buildStatsComment()
    else:

        #The basic algorithm here is:
        #If it's an expanded request, build a reply using the data in the braces, clear the arrays, add the reply to the relevant array and ignore everything else.
        #If it's a normal request, build a reply using the data in the braces, add the reply to the relevant array.

        #Counts the number of expanded results vs total results. If it's not just a single expanded result, they all get turned into normal requests.
        numOfRequest = 0
        numOfExpandedRequest = 0
        forceNormal = False
        for match in re.finditer("\{{2}([^}]*)\}{2}|\<{2}([^>]*)\>{2}",
                                 cleanMessage, re.S):
            numOfRequest += 1
            numOfExpandedRequest += 1

        for match in re.finditer(
                "(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))|(?<=(?<!\<)\<)([^\<\>]*)(?=\>(?!\>))",
                cleanMessage, re.S):
            numOfRequest += 1

        if (numOfExpandedRequest >= 1) and (numOfRequest > 1):
            forceNormal = True

        #Expanded Anime
        for match in re.finditer("\{{2}([^}]*)\}{2}", cleanMessage, re.S):
            reply = ''
            if (forceNormal) or (str(message.channel).lower()
                                 in disableexpanded):
                reply = DiscordoragiSearch.buildAnimeReply(
                    match.group(1), message, False)
            else:
                reply = DiscordoragiSearch.buildAnimeReply(
                    match.group(1), message, True)

            if (reply is not None):
                animeArray.append(reply)

        #Normal Anime
        for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))",
                                 cleanMessage, re.S):
            reply = DiscordoragiSearch.buildAnimeReply(match.group(1), message,
                                                       False)

            if (reply is not None):
                animeArray.append(reply)

        #Expanded Manga
        #NORMAL EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}(?!(:|\>))", cleanMessage,
                                 re.S):
            reply = ''

            if (forceNormal) or (str(message.channel).lower()
                                 in disableexpanded):
                reply = DiscordoragiSearch.buildMangaReply(
                    match.group(1), message, False)
            else:
                reply = DiscordoragiSearch.buildMangaReply(
                    match.group(1), message, True)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}:\(([^)]+)\)", cleanMessage,
                                 re.S):
            reply = ''

            if (forceNormal) or (str(message.server).lower()
                                 in disableexpanded):
                reply = DiscordoragiSearch.buildMangaReplyWithAuthor(
                    match.group(1), match.group(2), message, False)
            else:
                reply = DiscordoragiSearch.buildMangaReplyWithAuthor(
                    match.group(1), match.group(2), message, True)

            if (reply is not None):
                mangaArray.append(reply)

        #Normal Manga
        #NORMAL
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]+)\>(?!(:|\>))",
                                 cleanMessage, re.S):
            reply = DiscordoragiSearch.buildMangaReply(match.group(1), message,
                                                       False)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]*)\>:\(([^)]+)\)",
                                 cleanMessage, re.S):
            reply = DiscordoragiSearch.buildMangaReplyWithAuthor(
                match.group(1), match.group(2), message, False)

            if (reply is not None):
                mangaArray.append(reply)

        #Expanded LN
        for match in re.finditer("\]{2}([^]]*)\[{2}", cleanMessage, re.S):
            reply = ''

            if (forceNormal) or (str(message.server).lower()
                                 in disableexpanded):
                reply = DiscordoragiSearch.buildLightNovelReply(
                    match.group(1), False, message)
            else:
                reply = DiscordoragiSearch.buildLightNovelReply(
                    match.group(1), True, message)

            if (reply is not None):
                lnArray.append(reply)

        #Normal LN
        for match in re.finditer("(?<=(?<!\])\])([^\]\[]*)(?=\[(?!\[))",
                                 cleanMessage, re.S):
            reply = DiscordoragiSearch.buildLightNovelReply(
                match.group(1), False, message)

            if (reply is not None):
                lnArray.append(reply)

        #Here is where we create the final reply to be posted

        #The final message reply. We add stuff to this progressively.
        messageReply = ''

        #Basically just to keep track of people posting the same title multiple times (e.g. {Nisekoi}{Nisekoi}{Nisekoi})
        postedAnimeTitles = []
        postedMangaTitles = []
        postedLNTitles = []

        #Adding all the anime to the final message. If there's manga too we split up all the paragraphs and indent them in Reddit markup by adding a '>', then recombine them
        for i, animeReply in enumerate(animeArray):
            if not (i is 0):
                messageReply += '\n\n'

            if not (animeReply['title'] in postedAnimeTitles):
                postedAnimeTitles.append(animeReply['title'])
                messageReply += animeReply['comment']

        if mangaArray:
            messageReply += '\n\n'

        #Adding all the manga to the final message
        for i, mangaReply in enumerate(mangaArray):
            if not (i is 0):
                messageReply += '\n\n'

            if not (mangaReply['title'] in postedMangaTitles):
                postedMangaTitles.append(mangaReply['title'])
                messageReply += mangaReply['comment']

        if lnArray:
            messageReply += '\n\n'

        #Adding all the manga to the final comment
        for i, lnReply in enumerate(lnArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (lnReply['title'] in postedLNTitles):
                postedLNTitles.append(lnReply['title'])
                messageReply += lnReply['comment']

        #If there are more than 10 requests, shorten them all
        if not (messageReply is '') and (len(animeArray) + len(mangaArray) >=
                                         10):
            messageReply = re.sub(r"\^\((.*?)\)", "", messageReply, flags=re.M)

    #If there was actually something found, add the signature and post the message to Reddit. Then, add the message to the "already seen" database.
    if not (messageReply is ''):
        messageReply += Config.getSignature()

        if is_edit:
            await Discord.client.send_message(message.channel, messageReply)
        else:
            try:
                print("Message created.\n")
                await Discord.client.send_message(message.channel,
                                                  messageReply)
            except discord.errors.Forbidden:
                print('Request from banned channel: ' + str(message.channel) +
                      '\n')
            except Exception:
                traceback.print_exc()

            try:
                DatabaseHandler.addMessage(message.id, message.author.id,
                                           message.server.id, True)
            except:
                traceback.print_exc()
    else:
        try:
            if is_edit:
                return None
            else:
                DatabaseHandler.addMessage(message.id, message.author.id,
                                           message.server.id, False)
        except:
            traceback.print_exc()
Beispiel #19
0
def process_comment(comment, is_edit=False):
    """ process dat comment """
    # Anime/Manga requests that are found go into separate arrays
    animeArray = []
    mangaArray = []
    lnArray = []
    vnArray = []

    # ignores all "code" markup (i.e. anything between backticks)
    comment.body = re.sub(r"\`[{<\[]+(.*?)[}>\]]+\`", "", comment.body)

    num_so_far = 0

    numOfRequest = 0
    numOfExpandedRequest = 0

    # Ignore any blacklisted users
    if (comment.author.name.lower() in user_blacklist):
        print('User in blacklist: ' + comment.author.name)
        commentReply = ''
    # This checks for requests. First up we check all known tags for the !stats request
    elif re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)', comment.body, re.S) is not None:
        username = USERNAME_PATTERN.search(comment.body)
        subreddit = SUBREDDIT_PATTERN.search(comment.body)

        if username:
            commentReply = CommentBuilder.buildStatsComment(
                username=username.group(1)
            )
        elif subreddit:
            commentReply = CommentBuilder.buildStatsComment(
                subreddit=subreddit.group(1)
            )
        else:
            commentReply = CommentBuilder.buildStatsComment()
    else:

        # The basic algorithm here is:
        # If it's an expanded request, build a reply using the data in the
        # braces, clear the arrays, add the reply to the relevant array and
        # ignore everything else. If it's a normal request, build a reply using
        # the data in the braces, add the reply to the relevant array.

        # Counts the number of expanded results vs total results. If it's not
        # just a single expanded result, they all get turned into normal
        # requests.

        forceNormal = False

        for match in find_requests('all', comment.body, expanded=True):
            numOfRequest += 1
            numOfExpandedRequest += 1

        for match in find_requests('all', comment.body):
            numOfRequest += 1

        if (numOfExpandedRequest >= 1) and (numOfRequest > 1):
            forceNormal = True

        # Determine whether we'll build an expanded reply just once.
        subredditName = str(comment.subreddit).lower()
        isExpanded = False if (forceNormal or (subredditName in disableexpanded)) else True

        # The final comment reply. We add stuff to this progressively.
        commentReply = ''

        # Expanded Anime
        for match in find_requests('anime', comment.body, expanded=True):
            if num_so_far < 30:
                reply = Search.buildAnimeReply(match, isExpanded, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    animeArray.append(reply)

        # Normal Anime
        for match in find_requests('anime', comment.body):
            if num_so_far < 30:
                reply = Search.buildAnimeReply(match, False, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    animeArray.append(reply)

        # Expanded Manga
        # NORMAL EXPANDED
        for match in find_requests('manga', comment.body, expanded=True):
            if num_so_far < 30:
                reply = Search.buildMangaReply(match, isExpanded, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    mangaArray.append(reply)

        # Normal Manga
        # NORMAL
        for match in find_requests('manga', comment.body):
            if num_so_far < 30:
                reply = Search.buildMangaReply(match, False, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    mangaArray.append(reply)

        # Expanded LN
        for match in find_requests('light_novel', comment.body, expanded=True):
            if num_so_far < 30:
                reply = Search.buildLightNovelReply(match, isExpanded, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    lnArray.append(reply)

        # Normal LN
        for match in find_requests('light_novel', comment.body):
            if num_so_far < 30:
                reply = Search.buildLightNovelReply(match, False, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    lnArray.append(reply)

        # Expanded VN
        for match in find_requests('visual_novel', comment.body, expanded=True):
            if num_so_far < 30:
                reply = Search.buildVisualNovelReply(match, isExpanded, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    vnArray.append(reply)

        # Normal VN
        for match in find_requests('visual_novel', comment.body):
            if num_so_far < 30:
                reply = Search.buildVisualNovelReply(match, False, comment)

                if (reply is not None):
                    num_so_far = num_so_far + 1
                    vnArray.append(reply)

        # Here is where we create the final reply to be posted

        # Basically just to keep track of people posting the same title
        # multiple times (e.g. {Nisekoi}{Nisekoi}{Nisekoi})
        postedAnimeTitles = []
        postedMangaTitles = []
        postedLNTitles = []
        postedVNTitles = []

        # Adding all the anime to the final comment. If there's manga too we
        # split up all the paragraphs and indent them in Reddit markup by
        # adding a '>', then recombine them
        for i, animeReply in enumerate(animeArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (animeReply['title'] in postedAnimeTitles):
                postedAnimeTitles.append(animeReply['title'])
                commentReply += animeReply['comment']

        if mangaArray:
            commentReply += '\n\n'

        # Adding all the manga to the final comment
        for i, mangaReply in enumerate(mangaArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (mangaReply['title'] in postedMangaTitles):
                postedMangaTitles.append(mangaReply['title'])
                commentReply += mangaReply['comment']

        if lnArray:
            commentReply += '\n\n'

        # Adding all the light novels to the final comment
        for i, lnReply in enumerate(lnArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (lnReply['title'] in postedLNTitles):
                postedLNTitles.append(lnReply['title'])
                commentReply += lnReply['comment']

        if vnArray:
            commentReply += '\n\n'

        # Adding all the visual novels to the final comment
        for i, vnReply in enumerate(vnArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (vnReply['title'] in postedVNTitles):
                postedVNTitles.append(vnReply['title'])
                commentReply += vnReply['comment']

        # If there are more than 10 requests, shorten them all
        lenRequests = sum(map(len, (animeArray, mangaArray, lnArray, vnArray)))
        if not (commentReply is '') and (lenRequests >= 10):
            commentReply = re.sub(r"\^\((.*?)\)", "", commentReply, flags=re.M)

    # If there was actually something found, add the signature and post the
    # comment to Reddit. Then, add the comment to the "already seen" database.
    if commentReply is not '':

        if num_so_far >= 30:
            commentReply += ("\n\nI'm limited to 30 requests at once and have "
                             "had to cut off some, sorry for the "
                             "inconvenience!\n\n")

        commentReply += Config.getSignature(comment.permalink)

        commentReply += Reference.get_bling(comment.author.name)

        total_expected = int(numOfRequest)
        total_found = sum(map(len, (animeArray, mangaArray, lnArray, vnArray)))

        if total_found != total_expected:
            commentReply += '&#32;|&#32;({0}/{1})'.format(total_found,
                                                          total_expected)

        if is_edit:
            return commentReply
        else:
            try:
                comment.reply(commentReply)
                print("Comment made.\n")
            except praw.errors.Forbidden:
                print('Request from banned '
                      'subreddit: {0}\n'.format(comment.subreddit))
            except Exception as e:
                logger.debug(traceback.print_exc())
                logger.warn(e)

            comment_author = comment.author.name if comment.author else '!UNKNOWN!'

            try:
                DatabaseHandler.addComment(
                    comment.id,
                    comment_author,
                    comment.subreddit,
                    True
                )
            except Exception as e:
                logger.debug(traceback.print_exc())
                logger.warn(e)
    else:
        try:
            if is_edit:
                return None
            else:
                comment_author = comment.author.name if comment.author else '!UNKNOWN!'

                DatabaseHandler.addComment(
                    comment.id,
                    comment_author,
                    comment.subreddit,
                    False
                )
        except Exception as e:
            logger.debug(traceback.print_exc())
            logger.warn(e)
Beispiel #20
0
def buildLightNovelReply(searchText,
                         isExpanded,
                         baseComment,
                         blockTracking=False):
    try:
        mal = {
            'search_function': MAL.getLightNovelDetails,
            'synonym_function': MAL.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        ani = {
            'search_function': Anilist.getLightNovelDetails,
            'synonym_function': Anilist.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        nu = {'search_function': NU.getLightNovelURL, 'result': None}
        lndb = {'search_function': LNDB.getLightNovelURL, 'result': None}

        try:
            sqlCur.execute(
                'SELECT dbLinks FROM synonyms WHERE type = "LN" and lower(name) = ?',
                [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                malsyn = None
                if 'mal' in synonym and synonym['mal']:
                    malsyn = synonym['mal']

                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                nusyn = None
                if 'nu' in synonym and synonym['nu']:
                    nusyn = synonym['nu']

                lndbsyn = None
                if 'lndb' in synonym and synonym['lndb']:
                    lndbsyn = synonym['lndb']

                mal['result'] = MAL.getLightNovelDetails(
                    malsyn[0], malsyn[1]) if malsyn else None
                ani['result'] = Anilist.getMangaDetailsById(
                    anisyn) if anisyn else None
                nu['result'] = NU.getLightNovelById(nusyn) if nusyn else None
                lndb['result'] = LNDB.getLightNovelById(
                    lndbsyn) if lndbsyn else None

        else:
            data_sources = [ani, mal]
            aux_sources = [nu, lndb]

            synonyms = set([searchText])

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in synonyms:
                            if synonym in source['checked_synonyms']:
                                continue

                            source['result'] = source['search_function'](
                                synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        synonyms.update([
                            synonym.lower() for synonym in
                            source['synonym_function'](source['result'])
                        ])

            for source in aux_sources:
                for synonym in synonyms:
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

        if ani['result'] or mal['result']:
            try:
                titleToAdd = ''
                if mal['result']:
                    titleToAdd = mal['result']['title']
                if ani['result']:
                    try:
                        titleToAdd = ani['result']['title_romaji']
                    except:
                        titleToAdd = ani['result']['title_english']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (
                        str(baseComment.subreddit).lower
                        is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'LN',
                                               baseComment.author.name,
                                               baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

        return CommentBuilder.buildLightNovelComment(isExpanded, mal['result'],
                                                     ani['result'],
                                                     nu['result'],
                                                     lndb['result'])

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #21
0
async def buildAnimeReply(searchText,
                          message,
                          isExpanded,
                          canEmbed,
                          blockTracking=False):
    try:
        mal = {
            'search_function': MAL.getAnimeDetails,
            'synonym_function': MAL.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        ani = {
            'search_function': Anilist.getAnimeDetails,
            'synonym_function': Anilist.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        ap = {'search_function': AniP.getAnimeURL, 'result': None}
        adb = {'search_function': AniDB.getAnimeURL, 'result': None}

        try:
            sqlCur.execute(
                'SELECT dbLinks FROM synonyms WHERE type = "Anime" and lower(name) = ?',
                [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                malsyn = None
                if 'mal' in synonym and synonym['mal']:
                    malsyn = synonym['mal']
                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                apsyn = None
                if 'ap' in synonym and synonym['ap']:
                    apsyn = synonym['ap']

                adbsyn = None
                if 'adb' in synonym and synonym['adb']:
                    adbsyn = synonym['adb']

                mal['result'] = await MAL.getAnimeDetails(
                    malsyn[0], malsyn[1]) if malsyn else None
                ani['result'] = await Anilist.getAnimeDetailsById(
                    anisyn) if anisyn else None
                ap['result'] = AniP.getAnimeURLById(apsyn) if apsyn else None
                adb['result'] = AniDB.getAnimeURLById(
                    adbsyn) if adbsyn else None
                print(ani['result'])

        else:
            data_sources = [ani, mal]
            aux_sources = [ap, adb]
            #aux_sources = [ap]

            synonyms = set([searchText])

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in synonyms:
                            if synonym in source['checked_synonyms']:
                                continue

                            source['result'] = await source['search_function'](
                                synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        synonyms.update([
                            synonym.lower() for synonym in
                            source['synonym_function'](source['result'])
                        ])

            for source in aux_sources:
                for synonym in synonyms:
                    source['result'] = await source['search_function'](synonym)

                    if source['result']:
                        break

        if ani['result'] or mal['result']:
            try:
                titleToAdd = ''
                if mal['result']:
                    if 'title' in mal['result']:
                        titleToAdd = mal['result']['title']
                '''if hb['result']:
                    if 'title' in hb['result']:
                        titleToAdd = hb['result']['title']'''
                if ani['result']:
                    if 'title_romaji' in ani['result']:
                        titleToAdd = ani['result']['title_romaji']

                if not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Anime',
                                               message.author.id,
                                               message.server.id)
            except:
                traceback.print_exc()
                pass
        if mal['result']:
            print('trying to add an anime to cache')
            try:
                DatabaseHandler.addMalEntry('malanime', mal['result'])
            except:
                traceback.print_exc()
                pass
        if ani:
            try:
                DatabaseHandler.addAniEntry('anilistanime', ani['result'])
            except:
                traceback.print_exc()
                pass
        if not canEmbed:
            return CommentBuilder.buildAnimeComment(isExpanded, mal['result'],
                                                    ani['result'],
                                                    ap['result'],
                                                    adb['result'])
        else:
            return CommentBuilder.buildAnimeEmbed(isExpanded, mal['result'],
                                                  ani['result'], ap['result'],
                                                  adb['result'])

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #22
0
def buildMangaReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:
        ani = None
        mal = None
        mu = None
        ap = None

        try:
            sqlCur.execute(
                'SELECT dbLinks FROM synonyms WHERE type = "Manga" and lower(name) = ?',
                [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if (synonym['mal']):
                mal = MAL.getMangaDetails(synonym['mal'][0], synonym['mal'][1])
            if (synonym['ani']):
                ani = Anilist.getMangaDetailsById(synonym['ani'])
            if (synonym['mu']):
                mu = MU.getMangaURLById(synonym['mu'])
            if (synonym['ap']):
                ap = AniP.getMangaURLById(synonym['ap'])

        else:
            #Basic breakdown:
            #If Anilist finds something, use it to find the MAL version.
            #If hits either MAL or Ani, use it to find the MU version.
            #If it hits either, add it to the request-tracking DB.
            ani = Anilist.getMangaDetails(searchText)

            if ani:
                try:
                    mal = MAL.getMangaDetails(ani['title_romaji'])
                except:
                    pass

                if not mal:
                    try:
                        mal = MAL.getMangaDetails(ani['title_english'])
                    except:
                        pass

                if not mal:
                    mal = MAL.getMangaDetails(searchText)

            else:
                mal = MAL.getMangaDetails(searchText)

                if mal:
                    ani = Anilist.getMangaDetails(mal['title'])

        #----- Finally... -----#
        if ani or mal:
            try:
                titleToAdd = ''
                if mal:
                    titleToAdd = mal['title']
                else:
                    try:
                        titleToAdd = ani['title_english']
                    except:
                        titleToAdd = ani['title_romaji']

                if not alternateLinks:
                    #MU stuff
                    if mal:
                        mu = MU.getMangaURL(mal['title'])
                    else:
                        mu = MU.getMangaURL(ani['title_romaji'])

                    #Do the anime-planet stuff
                    if mal and not ap:
                        if mal['title'] and not ap:
                            ap = AniP.getMangaURL(mal['title'])
                        if mal['english'] and not ap:
                            ap = AniP.getMangaURL(mal['english'])
                        if mal['synonyms'] and not ap:
                            for synonym in mal['synonyms']:
                                if ap:
                                    break
                                ap = AniP.getMangaURL(synonym)

                    if ani and not ap:
                        if ani['title_english'] and not ap:
                            ap = AniP.getMangaURL(ani['title_english'])
                        if ani['title_romaji'] and not ap:
                            ap = AniP.getMangaURL(ani['title_romaji'])
                        if ani['synonyms'] and not ap:
                            for synonym in ani['synonyms']:
                                if ap:
                                    break
                                ap = AniP.getMangaURL(synonym)

                if (str(baseComment.subreddit).lower is not 'nihilate') and (
                        str(baseComment.subreddit).lower
                        is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Manga',
                                               baseComment.author.name,
                                               baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

        return CommentBuilder.buildMangaComment(isExpanded, mal, ani, mu, ap)

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #23
0
def buildLightNovelReply(searchText,
                         isExpanded,
                         baseComment,
                         blockTracking=False):
    """ Builds an LN reply from multiple sources """
    try:
        ani = {
            'search_function': Anilist.getLightNovelDetails,
            'synonym_function': Anilist.getSynonyms,
            'title_function': Anilist.getTitles,
            'checked_synonyms': [],
            'result': None
        }
        kit = {
            'search_function': Kitsu.search_light_novel,
            'synonym_function': Kitsu.get_synonyms,
            'title_function': Kitsu.get_titles,
            'checked_synonyms': [],
            'result': None
        }
        nu = {'search_function': NU.getLightNovelURL, 'result': None}
        lndb = {'search_function': LNDB.getLightNovelURL, 'result': None}

        try:
            query = ('SELECT dbLinks'
                     '  FROM synonyms'
                     ' WHERE type = "LN"'
                     '   AND lower(name) = ?')
            sqlCur.execute(query, [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                kitsyn = None
                if 'kit' in synonym and synonym['kit']:
                    kitsyn = synonym['kit']

                nusyn = None
                if 'nu' in synonym and synonym['nu']:
                    nusyn = synonym['nu']

                lndbsyn = None
                if 'lndb' in synonym and synonym['lndb']:
                    lndbsyn = synonym['lndb']

                if anisyn:
                    ani['result'] = Anilist.getMangaDetailsById(anisyn)
                else:
                    ani['result'] = None

                if kitsyn:
                    kit['result'] = Kitsu.get_light_novel(kitsyn)
                else:
                    kit['result'] = None

                nu['result'] = NU.getLightNovelById(nusyn) if nusyn else None

                if lndbsyn:
                    lndb['result'] = LNDB.getLightNovelById(lndbsyn)
                else:
                    lndb['result'] = None

        else:
            data_sources = [ani, kit]
            aux_sources = [nu, lndb]

            synonyms = set([searchText])
            titles = set()

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in (titles | synonyms):
                            if synonym in source['checked_synonyms']:
                                continue

                            search_function = source['search_function']
                            source['result'] = search_function(synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        result = source['result']
                        synonym_function = source['synonym_function']
                        title_function = source['title_function']
                        synonyms.update(
                            [s.lower() for s in synonym_function(result)])
                        titles.update(
                            [t.lower() for t in title_function(result)])

            for source in aux_sources:
                for title in titles:
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

                if not source['result']:
                    for synonym in synonyms:
                        source['result'] = source['search_function'](synonym)

                        if source['result']:
                            break

        if ani['result'] or kit['result']:
            try:
                titleToAdd = ''
                if ani['result']:
                    try:
                        titleToAdd = ani['result']['title_romaji']
                    except Exception:
                        titleToAdd = ani['result']['title_english']
                elif kit['result']:
                    try:
                        titleToAdd = kit['result']['title_romaji']
                    except Exception:
                        titleToAdd = kit['result']['title_english']

                subreddit = str(baseComment.subreddit).lower
                ignored_subreddits = ('nihilate', 'roboragi')
                if subreddit not in ignored_subreddits and not blockTracking:
                    DatabaseHandler.addRequest(
                        name=titleToAdd,
                        rType='LN',
                        requester=baseComment.author.name,
                        subreddit=baseComment.subreddit)
            except Exception:
                traceback.print_exc()
                pass

        if ani['result'] or kit['result']:
            return CommentBuilder.buildLightNovelComment(isExpanded=isExpanded,
                                                         ani=ani['result'],
                                                         nu=nu['result'],
                                                         lndb=lndb['result'],
                                                         kit=kit['result'])
        else:
            print('No result found for ' + searchText)
            return None

    except Exception:
        traceback.print_exc()
        return None
Beispiel #24
0
def buildMangaReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:
        ani = None
        mal = None
        mu = None
        ap = None
        
        try:
            sqlCur.execute('SELECT dbLinks FROM synonyms WHERE type = "Manga" and lower(name) = ?', [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])
            
            if (synonym['mal']):
                mal = MAL.getMangaDetails(synonym['mal'])
            if (synonym['ani']):
                ani = Anilist.getMangaDetails(synonym['ani'])
            if (synonym['mu']):
                mu = MU.getMangaURL(synonym['mu'])
            if (synonym['ap']):
                ap = AniP.getMangaURL(synonym['ap'])

        else:
            #Basic breakdown:
            #If Anilist finds something, use it to find the MAL version.
            #If hits either MAL or Ani, use it to find the MU version.
            #If it hits either, add it to the request-tracking DB.
            ani = Anilist.getMangaDetails(searchText)
            
            if not (ani is None):
                mal = MAL.getMangaDetails(ani['title_romaji'])

            else:
                mal = MAL.getMangaDetails(searchText)

                if not (mal is None):
                    ani = Anilist.getMangaDetails(mal['title'])    

        #----- Finally... -----#
        if ani or mal:
            try:
                titleToAdd = ''
                if mal:
                    titleToAdd = mal['title']
                else:
                    titleToAdd = ani['title_english']

                
                if not alternateLinks:
                    #MU stuff
                    if mal:
                        mu = MU.getMangaURL(mal['title'])
                    else:
                        mu = MU.getMangaURL(ani['title_romaji'])

                    #Do the anime-planet stuff
                    if mal and not ap:
                        if mal['title'] and not ap:
                            ap = AniP.getMangaURL(mal['title'])
                        if mal['english'] and not ap:
                            ap = AniP.getMangaURL(mal['english'])
                        if mal['synonyms'] and not ap:
                            for synonym in mal['synonyms']:
                                if ap:
                                    break
                                ap = AniP.getMangaURL(synonym)

                    if ani and not ap:
                        if ani['title_english'] and not ap:
                            ap = AniP.getMangaURL(ani['title_english'])
                        if ani['title_romaji'] and not ap:
                            ap = AniP.getMangaURL(ani['title_romaji'])
                        if ani['synonyms'] and not ap:
                            for synonym in ani['synonyms']:
                                if ap:
                                    break
                                ap = AniP.getMangaURL(synonym)

                if (str(baseComment.subreddit).lower is not 'nihilate') and (str(baseComment.subreddit).lower is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Manga', baseComment.author.name, baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

        if ani is not None:
            if ani['adult'] is True:
                mal = None
                ani = None
                mu = None
                ap = None
        
        return CommentBuilder.buildMangaComment(isExpanded, mal, ani, mu, ap)
        
    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #25
0
def buildLightNovelReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:
        mal = {'search_function': MAL.getLightNovelDetails,
                'synonym_function': MAL.getSynonyms,
                'checked_synonyms': [],
                'result': None}
        ani = {'search_function': Anilist.getLightNovelDetails,
                'synonym_function': Anilist.getSynonyms,
                'checked_synonyms': [],
                'result': None}
        nu = {'search_function': NU.getLightNovelURL,
                'result': None}
        lndb = {'search_function': LNDB.getLightNovelURL,
                'result': None}
        
        try:
            sqlCur.execute('SELECT dbLinks FROM synonyms WHERE type = "LN" and lower(name) = ?', [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                malsyn = None
                if 'mal' in synonym and synonym['mal']:
                    malsyn = synonym['mal']

                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                nusyn = None
                if 'nu' in synonym and synonym['nu']:
                    nusyn = synonym['nu']

                lndbsyn = None
                if 'lndb' in synonym and synonym['lndb']:
                    lndbsyn = synonym['lndb']

                mal['result'] = MAL.getLightNovelDetails(malsyn[0],malsyn[1]) if malsyn else None
                ani['result'] = Anilist.getMangaDetailsById(anisyn) if anisyn else None
                nu['result'] = NU.getLightNovelById(nusyn) if nusyn else None
                lndb['result'] = LNDB.getLightNovelById(lndbsyn) if lndbsyn else None
                
        else:
            data_sources = [ani, mal]
            aux_sources = [nu, lndb]

            synonyms = set([searchText])

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in synonyms:
                            if synonym in source['checked_synonyms']:
                                continue

                            source['result'] = source['search_function'](synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        synonyms.update([synonym.lower() for synonym in source['synonym_function'](source['result'])])

            for source in aux_sources:
                for synonym in synonyms:     
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

        if ani['result'] or mal['result']:
            try:
                titleToAdd = ''
                if mal['result']:
                    titleToAdd = mal['result']['title']
                if ani['result']:
                    try:
                        titleToAdd = ani['result']['title_romaji']
                    except:
                        titleToAdd = ani['result']['title_english']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (str(baseComment.subreddit).lower is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'LN', baseComment.author.name, baseComment.subreddit)
            except:
                traceback.print_exc()
                pass
        
        return CommentBuilder.buildLightNovelComment(isExpanded, mal['result'], ani['result'], nu['result'], lndb['result'])

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #26
0
def buildMangaReply(searchText, isExpanded, baseComment, blockTracking=False):
    try:
        ani = {
            'search_function': Anilist.getMangaDetails,
            'synonym_function': Anilist.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        mal = {
            'search_function': MAL.getMangaDetails,
            'synonym_function': MAL.getSynonyms,
            'checked_synonyms': [],
            'result': None
        }
        kit = {
            'search_function': Kitsu.search_manga,
            'synonym_function': Kitsu.get_synonyms,
            'checked_synonyms': [],
            'result': None
        }
        mu = {'search_function': MU.getMangaURL, 'result': None}
        ap = {'search_function': AniP.getMangaURL, 'result': None}

        try:
            sqlCur.execute(
                'SELECT dbLinks FROM synonyms WHERE type = "Manga" and lower(name) = ?',
                [searchText.lower()])
        except sqlite3.Error as e:
            print(e)

        alternateLinks = sqlCur.fetchone()

        if (alternateLinks):
            synonym = json.loads(alternateLinks[0])

            if synonym:
                malsyn = None
                if 'mal' in synonym and synonym['mal']:
                    malsyn = synonym['mal']

                anisyn = None
                if 'ani' in synonym and synonym['ani']:
                    anisyn = synonym['ani']

                kitsyn = None
                if 'kit' in synonym and synonym['kit']:
                    kitsyn = synonym['kit']

                musyn = None
                if 'mu' in synonym and synonym['mu']:
                    musyn = synonym['mu']

                apsyn = None
                if 'ap' in synonym and synonym['ap']:
                    apsyn = synonym['ap']

                mal['result'] = MAL.getMangaDetails(
                    malsyn[0], malsyn[1]) if malsyn else None
                ani['result'] = Anilist.getMangaDetailsById(
                    anisyn) if anisyn else None
                kit['result'] = Kitsu.get_manga(kitsyn) if kitsyn else None
                mu['result'] = MU.getMangaURLById(musyn) if musyn else None
                ap['result'] = AniP.getMangaURLById(apsyn) if apsyn else None

        else:
            data_sources = [ani, kit, mal]
            aux_sources = [mu, ap]

            synonyms = set([searchText])

            for x in range(len(data_sources)):
                for source in data_sources:
                    if source['result']:
                        break
                    else:
                        for synonym in synonyms:
                            if synonym in source['checked_synonyms']:
                                continue

                            source['result'] = source['search_function'](
                                synonym)
                            source['checked_synonyms'].append(synonym)

                            if source['result']:
                                break

                    if source['result']:
                        synonyms.update([
                            synonym.lower() for synonym in
                            source['synonym_function'](source['result'])
                        ])

            for source in aux_sources:
                for synonym in synonyms:
                    source['result'] = source['search_function'](synonym)

                    if source['result']:
                        break

        if ani['result'] or mal['result'] or kit['result']:
            try:
                titleToAdd = ''
                if ani['result']:
                    try:
                        titleToAdd = ani['result']['title_romaji']
                    except:
                        titleToAdd = ani['result']['title_english']
                elif mal['result']:
                    titleToAdd = mal['result']['title']
                elif kit['result']:
                    try:
                        titleToAdd = kit['result']['title_romaji']
                    except:
                        titleToAdd = kit['result']['title_english']

                if (str(baseComment.subreddit).lower is not 'nihilate') and (
                        str(baseComment.subreddit).lower
                        is not 'roboragi') and not blockTracking:
                    DatabaseHandler.addRequest(titleToAdd, 'Manga',
                                               baseComment.author.name,
                                               baseComment.subreddit)
            except:
                traceback.print_exc()
                pass

        return CommentBuilder.buildMangaComment(isExpanded, mal['result'],
                                                ani['result'], mu['result'],
                                                ap['result'], kit['result'])

    except Exception as e:
        traceback.print_exc()
        return None
Beispiel #27
0
def process_comment(comment, is_edit=False):
    #Anime/Manga requests that are found go into separate arrays
    animeArray = []
    mangaArray = []
    lnArray = []

    #ignores all "code" markup (i.e. anything between backticks)
    comment.body = re.sub(r"\`(?s)(.*?)\`", "", comment.body)

    #This checks for requests. First up we check all known tags for the !stats request
    if re.search('({!stats.*?}|{{!stats.*?}}|<!stats.*?>|<<!stats.*?>>)',
                 comment.body, re.S) is not None:
        username = re.search('[uU]\/([A-Za-z0-9_-]+?)(>|}|$)', comment.body,
                             re.S)
        subreddit = re.search('[rR]\/([A-Za-z0-9_]+?)(>|}|$)', comment.body,
                              re.S)

        if username:
            commentReply = CommentBuilder.buildStatsComment(
                username=username.group(1))
        elif subreddit:
            commentReply = CommentBuilder.buildStatsComment(
                subreddit=subreddit.group(1))
        else:
            commentReply = CommentBuilder.buildStatsComment()
    else:

        #The basic algorithm here is:
        #If it's an expanded request, build a reply using the data in the braces, clear the arrays, add the reply to the relevant array and ignore everything else.
        #If it's a normal request, build a reply using the data in the braces, add the reply to the relevant array.

        #Counts the number of expanded results vs total results. If it's not just a single expanded result, they all get turned into normal requests.
        numOfRequest = 0
        numOfExpandedRequest = 0
        forceNormal = False

        for match in re.finditer("\{{2}([^}]*)\}{2}|\<{2}([^>]*)\>{2}",
                                 comment.body, re.S):
            numOfRequest += 1
            numOfExpandedRequest += 1

        for match in re.finditer(
                "(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))|(?<=(?<!\<)\<)([^\<\>]*)(?=\>(?!\>))",
                comment.body, re.S):
            numOfRequest += 1

        if (numOfExpandedRequest >= 1) and (numOfRequest > 1):
            forceNormal = True

        #Expanded Anime
        for match in re.finditer("\{{2}([^}]*)\}{2}", comment.body, re.S):
            reply = ''

            if (forceNormal) or (str(comment.subreddit).lower()
                                 in disableexpanded):
                reply = Search.buildAnimeReply(match.group(1), False, comment)
            else:
                reply = Search.buildAnimeReply(match.group(1), True, comment)

            if (reply is not None):
                animeArray.append(reply)

        #Normal Anime
        for match in re.finditer("(?<=(?<!\{)\{)([^\{\}]*)(?=\}(?!\}))",
                                 comment.body, re.S):
            reply = Search.buildAnimeReply(match.group(1), False, comment)

            if (reply is not None):
                animeArray.append(reply)

        #Expanded Manga
        #NORMAL EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}(?!(:|\>))", comment.body,
                                 re.S):
            reply = ''

            if (forceNormal) or (str(comment.subreddit).lower()
                                 in disableexpanded):
                reply = Search.buildMangaReply(match.group(1), False, comment)
            else:
                reply = Search.buildMangaReply(match.group(1), True, comment)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH EXPANDED
        for match in re.finditer("\<{2}([^>]*)\>{2}:\(([^)]+)\)", comment.body,
                                 re.S):
            reply = ''

            if (forceNormal) or (str(comment.subreddit).lower()
                                 in disableexpanded):
                reply = Search.buildMangaReplyWithAuthor(
                    match.group(1), match.group(2), False, comment)
            else:
                reply = Search.buildMangaReplyWithAuthor(
                    match.group(1), match.group(2), True, comment)

            if (reply is not None):
                mangaArray.append(reply)

        #Normal Manga
        #NORMAL
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]+)\>(?!(:|\>))",
                                 comment.body, re.S):
            reply = Search.buildMangaReply(match.group(1), False, comment)

            if (reply is not None):
                mangaArray.append(reply)

        #AUTHOR SEARCH
        for match in re.finditer("(?<=(?<!\<)\<)([^\<\>]*)\>:\(([^)]+)\)",
                                 comment.body, re.S):
            reply = Search.buildMangaReplyWithAuthor(match.group(1),
                                                     match.group(2), False,
                                                     comment)

            if (reply is not None):
                mangaArray.append(reply)

        #Expanded LN
        for match in re.finditer("\]{2}([^]]*)\[{2}", comment.body, re.S):
            reply = ''

            if (forceNormal) or (str(comment.subreddit).lower()
                                 in disableexpanded):
                reply = Search.buildLightNovelReply(match.group(1), False,
                                                    comment)
            else:
                reply = Search.buildLightNovelReply(match.group(1), True,
                                                    comment)

            if (reply is not None):
                lnArray.append(reply)

        #Normal LN
        for match in re.finditer("(?<=(?<!\])\])([^\]\[]*)(?=\[(?!\[))",
                                 comment.body, re.S):
            reply = Search.buildLightNovelReply(match.group(1), False, comment)

            if (reply is not None):
                lnArray.append(reply)

        #Here is where we create the final reply to be posted

        #The final comment reply. We add stuff to this progressively.
        commentReply = ''

        #Basically just to keep track of people posting the same title multiple times (e.g. {Nisekoi}{Nisekoi}{Nisekoi})
        postedAnimeTitles = []
        postedMangaTitles = []
        postedLNTitles = []

        #Adding all the anime to the final comment. If there's manga too we split up all the paragraphs and indent them in Reddit markup by adding a '>', then recombine them
        for i, animeReply in enumerate(animeArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (animeReply['title'] in postedAnimeTitles):
                postedAnimeTitles.append(animeReply['title'])
                commentReply += animeReply['comment']

        if mangaArray:
            commentReply += '\n\n'

        #Adding all the manga to the final comment
        for i, mangaReply in enumerate(mangaArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (mangaReply['title'] in postedMangaTitles):
                postedMangaTitles.append(mangaReply['title'])
                commentReply += mangaReply['comment']

        if lnArray:
            commentReply += '\n\n'

        #Adding all the manga to the final comment
        for i, lnReply in enumerate(lnArray):
            if not (i is 0):
                commentReply += '\n\n'

            if not (lnReply['title'] in postedLNTitles):
                postedLNTitles.append(lnReply['title'])
                commentReply += lnReply['comment']

        #If there are more than 10 requests, shorten them all
        if not (commentReply is '') and (
                len(animeArray) + len(mangaArray) + len(lnArray) >= 10):
            commentReply = re.sub(r"\^\((.*?)\)", "", commentReply, flags=re.M)

    #If there was actually something found, add the signature and post the comment to Reddit. Then, add the comment to the "already seen" database.
    if commentReply is not '':
        '''if (comment.author.name == 'treborabc'):
            commentReply = '[No.](https://www.reddit.com/r/anime_irl/comments/4sba1n/anime_irl/d58xkha)'''

        commentReply += Config.getSignature(comment.permalink)

        commentReply += Reference.get_bling(comment.author.name)

        if is_edit:
            return commentReply
        else:
            try:
                comment.reply(commentReply)
                print("Comment made.\n")
            except praw.errors.Forbidden:
                print('Request from banned subreddit: ' +
                      str(comment.subreddit) + '\n')
            except Exception:
                traceback.print_exc()

            try:
                DatabaseHandler.addComment(comment.id, comment.author.name,
                                           comment.subreddit, True)
            except:
                traceback.print_exc()
    else:
        try:
            if is_edit:
                return None
            else:
                DatabaseHandler.addComment(comment.id, comment.author.name,
                                           comment.subreddit, False)
        except:
            traceback.print_exc()