Esempio n. 1
0
 def __init__(self, user_name):
     """
     Initializes the Instance Object. Its status should be checked through the
     property `k`.
     """
     if _Utils.user_exists(user_name) is False:
         self.k = False
         return None
     self.k = True
     self.udb = utils.Database().user
     self._user_dat = self.udb.find_one({"user_name": user_name})
     self._updates = set()
Esempio n. 2
0
 def __init__(self, survey_id):
     """
     Initializes the Instance Object. Its status should be checked through the
     property `k`.
     """
     if _Utils.survey_exists(survey_id) is False:
         self.k = False
         return None
     self.k = True
     self.sdb = utils.Database().survey
     self._survey_dat = self.sdb.find_one({"_id": ObjectId(survey_id)})
     self._updates = set()
Esempio n. 3
0
def generate_daily():
    date, terms = get_daily_papers()
    # insert to db
    log.info(f"add {len(terms)} papers to database")
    db = utils.Database(log)
    values = [(p.id, p.url, p.title, p.author, p.org, p.comment, p.subject)
              for p in terms]
    db.batch_update("arxiv", "paper_id",
                    "paper_id,url,title,author,org,comment,subject", values)
    db.close()
    # create html
    columns = ["Title", "Org", "Comment", "Author"]
    arxiv_raw = os.path.join(template_folder, "arxiv_raw.html")
    arxiv_pc = os.path.join(template_folder, "arxiv.html")
    pc_head = os.path.join(template_folder, "template_head.html")
    pc_tail = os.path.join(template_folder, "template_tail.html")
    with open(arxiv_raw, "w") as fout:
        fout.write('<div class="container pb-3">\n')
        fout.write(f'<p><kbd>Arxiv NLP - {date}</kbd></p>\n')
        fout.write('<p><kbd>本服务由微信公众号「夕小瑶的卖萌屋」提供</kbd></p>\n')
        fout.write('</div>\n')
        fout.write('<table style="width: 100%">\n')
        fout.write('<colgroup>\n')
        fout.write('<col span="1" style="width: 35%;">\n')
        fout.write('<col span="1" style="width: 15%;">\n')
        fout.write('<col span="1" style="width: 25%;">\n')
        fout.write('<col span="1" style="width: 35%;">\n')
        fout.write('</colgroup>\n')
        fout.write('<thead><tr class="table100-head">\n')
        for idx, column_name in enumerate(columns):
            if column_name == "Title":
                fout.write(f'<th class="text-center">{column_name}</th>\n')
            else:
                fout.write(f'<th>{column_name}</th>\n')
        fout.write('</tr></thead><tbody>\n')
        for paper in terms:
            fout.write('<tr>\n')
            fout.write(
                f"<td class='column3'><a href='{paper.url}'>{paper.title}</a></td>\n"
            )
            if len(paper.org) > 0:
                fout.write(f"<td class='column3'>{paper.org}</td>\n")
            else:
                fout.write(f"<td class='column3'>-</td>\n")
            if len(paper.comment) > 0:
                fout.write(f"<td class='column3'>{paper.comment}</td>\n")
            else:
                fout.write(f"<td class='column3'>-</td>\n")
            fout.write(f"<td class='column3'>{paper.author}</td>\n")
            fout.write('</tr>\n')
        fout.write('</table>\n')
    os.system(f"rm -rf {arxiv_pc}")
    os.system(f"cat {pc_head} {arxiv_raw} {pc_tail} >> {arxiv_pc}")
Esempio n. 4
0
    def add(scheme, tags, target, survey, filters):
        push_data = {
            'scheme': scheme(),
            'tags': tags,
            'target': target,
            'survey': survey(),
            'filters': filters(),
            'meta': {
                'added': datetime.datetime.utcnow()
            }
        }

        return (True,
                utils.Database().survey.insert_one(push_data).inserted_id)
Esempio n. 5
0
    def add(user_name, password, confirm_password, email_id):
        """Adds the User into Database."""
        errors = []

        if _Utils.validate_username(user_name) is False:
            errors.append("BadUserName")

        if _Utils.validate_email(email_id) is False:
            errors.append("BadEmailID")

        if _Utils.validate_password(password) is False:
            errors.append("ShortPassword")

        if _Utils.user_exists(user_name):
            errors.append("UsernameExist")

        if _Utils.email_exists(email_id):
            errors.append("EmailExist")

        if password != confirm_password:
            errors.append("PasswordNoMatch")

        if len(errors) is not 0:
            return (False, errors)
        else:
            user = {
                'user_name': user_name,
                'pswd': Password.get_hashed_password(password),
                'email': email_id,
                'status': 1,
                'meta': {
                    'added': datetime.datetime.utcnow()
                }
            }

            utils.Database().user.insert_one(user).inserted_id

            return (True, )
Esempio n. 6
0
 def __init__(self):
     self.database = utils.Database()
Esempio n. 7
0
 def email_exists(email_id):
     """
     Checks if the Email exists in Database.
     """
     return utils.Database().user.find_one({"email": email_id})
Esempio n. 8
0
 def user_exists(user_name):
     """
     Checks if the User exists in Database.
     """
     return utils.Database().user.find_one({"user_name":
                                            user_name}) is not None
Esempio n. 9
0
async def resume_verification_queue():
    guild = bot.get_guild(809900131494789120)
    verification_queue = guild.get_channel(811625549062733845)
    moderator_role = guild.get_role(810130497485275166)

    db = utils.Database(bot.db_path)

    async with aiosqlite.connect(bot.db_path) as conn:
        cursor = await conn.execute("SELECT * FROM submission_tracking ")
        submissions = [
            (submission_id, ast.literal_eval(submission))
            for submission_id, submission in await cursor.fetchall()
        ]
        await conn.commit()

    # Clean up previous messages for the same submission
    for submission_id, submission in submissions:
        for message in await verification_queue.history(limit=100).flatten():
            if message.embeds and message.embeds[
                    0].footer.text and message.embeds[
                        0].footer.text == submission_id:
                await message.delete()

        author = guild.get_member(int(submission["contributors"][0]))

        verification_message_embed = discord.Embed(
            title=f"Submission: {submission['name']}",
            # description="\n".join([f"**{s_name}:** {s_value}" for s_name, s_value in specs.items()]),
            colour=green)

        for item, value in submission.items():
            field_value = value

            if isinstance(value, list):
                value = [str(item) for item in value]
                field_value = f"{', '.join(value)}."

            if isinstance(value, dict):
                field_value = "\n".join([
                    f"**{entry_name}**: {entry_value}"
                    for entry_name, entry_value in value.items()
                ])

            verification_message_embed.add_field(name=item.capitalize(),
                                                 value=field_value,
                                                 inline=False)

        verification_message_embed.set_author(name=author,
                                              icon_url=author.avatar_url)
        verification_message_embed.set_footer(text=submission_id)

        verification_message = await verification_queue.send(
            embed=verification_message_embed)

        def reaction_check(r, u):
            return not u.bot and moderator_role in u.roles and r.emoji in (
                "✅", "❌") and r.message.id == verification_message.id

        for reaction in ("✅", "❌"):
            await verification_message.add_reaction(reaction)

        # Wait for a reaction on the submission in the verification queue
        # If no reaction is added and it times out, it will just be ignored.
        try:
            reaction, user = await bot.wait_for("reaction_add",
                                                check=reaction_check,
                                                timeout=86400)
        except asyncio.TimeoutError:
            ignored_embed = discord.Embed(
                description=
                f"Your submission for the part **{part}** has expired.",
                colour=green)
            await author.send(embed=ignored_embed)
            await db.add(author.id, "ignored")

            # Delete submission from database (in case the bot restarted)
            async with aiosqlite.connect("data.db") as conn:
                await conn.execute(
                    "DELETE FROM submission_tracking WHERE submission_id = ?",
                    (submission_id, ))
                await conn.commit()

            verification_message_embed.colour = grey
            await verification_message.edit(embed=verification_message_embed)
            return

        if reaction.emoji == "✅":
            await db.add_part(submission)

            approved_embed = discord.Embed(
                description=
                f"Your submission for the part **{submission['name']}** has been approved. Thank you for contributing!",
                colour=green)
            await author.send(embed=approved_embed)
            await db.add(author.id, "approved")

            # Delete submission from database (in case the bot restarted)
            async with aiosqlite.connect("data.db") as conn:
                await conn.execute(
                    "DELETE FROM submission_tracking WHERE submission_id = ?",
                    (submission_id, ))
                await conn.commit()

            verification_message_embed.colour = grey
            await verification_message.edit(embed=verification_message_embed)
        elif reaction.emoji == "❌":
            declined_embed = discord.Embed(
                description=
                f"Your submission for the part **{submission['name']}** has been declined.",
                colour=green)
            await author.send(embed=declined_embed)
            await db.add(author.id, "declined")

            # Delete submission from database (in case the bot restarted)
            async with aiosqlite.connect("data.db") as conn:
                await conn.execute(
                    "DELETE FROM submission_tracking WHERE submission_id = ?",
                    (submission_id, ))
                await conn.commit()

            verification_message_embed.colour = grey
            await verification_message.edit(embed=verification_message_embed)
Esempio n. 10
0
 def survey_exists(survey_id):
     """
     Checks if the Survey exists in Database.
     """
     return utils.Database().survey.find_one({"_id": ObjectId(survey_id)
                                              }) is not None
Esempio n. 11
0
    async def submit(self, ctx, *, part):
        if ctx.author.id == 790374236946432071:
            return

        part_submissions_category = ctx.guild.get_channel(810298926678540329)
        verification_queue = ctx.guild.get_channel(811625549062733845)
        moderator_role = ctx.guild.get_role(810130497485275166)
        specs = {}
        part_data = {}
        stop_message = discord.Embed(description="Stopping...", colour=green)
        chars = string.ascii_letters + string.digits

        def message_check(m):
            return m.channel == ctx.channel and m.author.id == ctx.author.id

        def cancel_message_check(m):
            return m.channel == ctx.channel and m.author.id == ctx.author.id and any(word in m.content for word in ("cancel", "send"))

        db = utils.Database(self.bot.db_path)
        results = await db.search_parts(name=part)

        # Check if there are any duplicates
        for result in results:
            if part.lower() == result[0].lower():
                duplicate = discord.Embed(description="That part already exists.", colour=green)
                await ctx.send(embed=duplicate)
                return

        required_information = {
            "type": ("Required", valid_part_types),
            "manufacturer": ("Required",),
            "sources": ("Recommended", "separate each item by a comma: `,`"),
            "images": ("Optional", "separate each URL by a comma: `,`"),
            "notes": ("Optional", "separate each item by a comma: `,`"),
        }

        # Ask for data about the part
        for item, item_info in required_information.items():
            question = f"Send the part {item} in chat:"

            if len(item_info) > 1 and isinstance(item_info[1], str):
                question = f"Specify the part {item} ({item_info[1]}) in chat:"

            question_embed = discord.Embed(description=question, colour=green)
            question_embed.set_footer(text=item_info[0])
            question_message = await ctx.send(embed=question_embed)

            response = await self.bot.wait_for("message", check=message_check, timeout=60)

            # Stop the data input if the user sends "stop"
            if "stop" in response.content.lower():
                question_embed.colour = grey
                await question_message.edit(embed=question_embed)
                await ctx.send(embed=stop_message)

                return

            # Skip the question if it's optional and the user sends "skip"
            if item_info[0] in ("Recommended", "Optional") and "skip" in response.content.lower():
                question_embed.colour = grey
                await question_message.edit(embed=question_embed)

                continue

            # Check if the user sent an image URL
            if item == "images":
                match = re.search(image_url_regex, response.content)
                skip = False

                while not match and skip is False:
                    question_embed.colour = grey
                    await question_message.edit(embed=question_embed)

                    invalid_image_url_embed = discord.Embed(
                        description="The image URL(s) you entered are invalid. Try again:",
                        colour=green)
                    invalid_image_url_message = await ctx.send(embed=invalid_image_url_embed)

                    response = await self.bot.wait_for("message", check=message_check, timeout=60)

                    if "stop" in response.content.lower():
                        invalid_image_url_embed.colour = grey
                        await invalid_image_url_message.edit(embed=invalid_image_url_embed)

                        await ctx.send(embed=stop_message)
                        return

                    if "skip" in response.content.lower():
                        invalid_image_url_embed.colour = grey
                        await invalid_image_url_message.edit(embed=invalid_image_url_embed)

                        skip = True
                        break

                    match = re.search(image_url_regex, response.content)

                    invalid_image_url_embed.colour = grey
                    await invalid_image_url_message.edit(embed=invalid_image_url_embed)

            # Check if the item is type and if the type is valid
            if len(item_info) > 1 and isinstance(item_info[1], tuple):
                while not response.content.lower() in valid_part_types_lower:
                    if "stop" in response.content.lower():
                        question_embed.colour = grey
                        await question_message.edit(embed=question_embed)
                        await ctx.send(embed=stop_message)

                        return

                    invalid_part_type = discord.Embed(
                        description=f"The type you entered is invalid. You must pick from: `{', '.join(valid_part_types)}.`",
                        colour=green
                    )
                    await ctx.send(embed=invalid_part_type)
                    response = await self.bot.wait_for("message", check=message_check, timeout=60)

            part_data[item] = response.content
            question_embed.colour = grey
            await question_message.edit(embed=question_embed)

        # Ask for the part specs
        while True:
            spec_name_embed = discord.Embed(description="What is the spec called?", colour=green)
            spec_name_message = await ctx.send(embed=spec_name_embed)
            spec_name = await self.bot.wait_for("message", check=message_check, timeout=60)

            if spec_name.content.lower() in [name.lower() for name in specs.keys()]:
                duplicate_spec = discord.Embed(description="That spec already exists!", colour=green)
                await ctx.send(embed=duplicate_spec)

                spec_name_embed.colour = grey
                await spec_name_message.edit(embed=spec_name_embed)

                continue

            if "stop" in spec_name.content.lower():
                spec_name_embed.colour = grey
                await spec_name_message.edit(embed=spec_name_embed)

                if specs:
                    formatted_data = "\n".join(
                        [f"**{item_name.capitalize()}**: {item_value}" for item_name, item_value in part_data.items()])
                    formatted_specs = "\n".join([f"**{s_name}:** {s_value}" for s_name, s_value in specs.items()])

                    stop_message = discord.Embed(
                        title="Submitted part data",
                        description="If you want to cancel the submission, type \"cancel\" within 60 seconds (in 60s "
                                    "it will automatically be sent."
                                    "If you want to send the submission, type \"send\".",
                        colour=green)
                    stop_message.add_field(name="Data", value=formatted_data, inline=False)
                    stop_message.add_field(name="Specs", value=formatted_specs, inline=False)
                    stop_message.set_footer(text="Your part will be submitted.")

                await ctx.send(embed=stop_message)

                # Let the user cancel the submission within 60s
                try:
                    cancel_message = await self.bot.wait_for("message", check=cancel_message_check, timeout=60)

                    if "cancel" in cancel_message.content.lower():
                        cancelled_embed = discord.Embed(description="Your submission has been cancelled.", colour=green)
                        await ctx.send(embed=cancelled_embed)

                        return
                    elif "send" in cancel_message.content.lower():
                        sent_embed = discord.Embed(description="Your submission has been sent.", colour=green)
                        await ctx.send(embed=sent_embed)

                except asyncio.TimeoutError:
                    pass

                # Break out of the loop asking for specs
                break

            spec_name_embed.colour = grey
            await spec_name_message.edit(embed=spec_name_embed)

            spec_values_embed = discord.Embed(
                description=f"What is the value of {spec_name.content}?\n(separate each item by a comma: `,`)",
                colour=green
            )
            spec_values_message = await ctx.send(embed=spec_values_embed)
            spec_values = await self.bot.wait_for("message", check=message_check, timeout=60)

            if "stop" in spec_values.content.lower():
                spec_values_embed.colour = grey
                await spec_values_message.edit(embed=spec_values_embed)

                if specs:
                    formatted_data = "\n".join(
                        [f"**{item_name.capitalize()}**: {item_value}" for item_name, item_value in part_data.items()])
                    formatted_specs = "\n".join([f"**{s_name}:** {s_value}" for s_name, s_value in specs.items()])

                    stop_message = discord.Embed(
                        title="Submitted part data",
                        description="If you want to cancel the submission, type \"cancel\" within 60 seconds (in 60s "
                                    "it will automatically be sent."
                                    "If you want to send the submission, type \"send\".",
                        colour=green)
                    stop_message.add_field(name="Data", value=formatted_data, inline=False)
                    stop_message.add_field(name="Specs", value=formatted_specs, inline=False)
                    stop_message.set_footer(text="Your part will be submitted.")

                await ctx.send(embed=stop_message)

                # Let the user cancel the submission within 60s
                try:
                    cancel_message = await self.bot.wait_for("message", check=cancel_message_check, timeout=60)

                    if "cancel" in cancel_message.content.lower():
                        cancelled_embed = discord.Embed(description="Your submission has been cancelled.", colour=green)
                        await ctx.send(embed=cancelled_embed)

                        return
                    elif "send" in cancel_message.content.lower():
                        sent_embed = discord.Embed(description="Your submission has been sent.", colour=green)
                        await ctx.send(embed=sent_embed)
                except asyncio.TimeoutError:
                    pass

                # Break out of the loop asking for specs
                break

            spec_values_embed.colour = grey
            await spec_values_message.edit(embed=spec_values_embed)

            # If the spec contains multiple values, it will make it a list, else it won't
            if len(spec_values.content.split(",")) == 1:
                specs[spec_name.content] = spec_values.content
            else:
                specs[spec_name.content] = spec_values.content.split(",")

        # If the user didn't add any specs, it won't send the part for verification
        if not specs:
            return

        # Process part data, send it to the verification system and act accordingly
        part_data["name"] = part
        part_data["specs"] = specs

        if "images" in part_data:
            part_data["images"] = part_data["images"].split(",")
        if "sources" in part_data:
            part_data["sources"] = part_data["sources"].split(",")
        if "notes" in part_data:
            part_data["notes"] = part_data["notes"].split(",")

        part_data["contributors"] = [str(ctx.author.id)]

        verification_message_embed = discord.Embed(
            title=f"Submission: {part}",
            # description="\n".join([f"**{s_name}:** {s_value}" for s_name, s_value in specs.items()]),
            colour=green
        )

        for item, value in part_data.items():
            field_value = value

            if isinstance(value, list):
                value = [str(item) for item in value]
                field_value = f"{', '.join(value)}."

            if isinstance(value, dict):
                field_value = "\n".join(
                    [f"**{entry_name}**: {entry_value}" for entry_name, entry_value in value.items()])

            verification_message_embed.add_field(name=item.capitalize(), value=field_value, inline=False)

        # Generate the submission ID
        submission_id = "".join([random.choice(chars) for x in range(6)])

        verification_message_embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
        verification_message_embed.set_footer(text=submission_id)

        verification_message = await verification_queue.send(embed=verification_message_embed)

        # Add submission to db (in case the bot restarts)
        async with aiosqlite.connect(self.bot.db_path) as conn:
            await conn.execute("INSERT into submission_tracking VALUES (?, ?)", (submission_id, str(part_data)))
            await conn.commit()

        def reaction_check(r, u):
            return not u.bot and moderator_role in u.roles and r.emoji in ("✅", "❌") and r.message.id == verification_message.id

        for reaction in ("✅", "❌"):
            await verification_message.add_reaction(reaction)

        # Wait for a reaction on the submission in the verification queue
        # If no reaction is added and it times out, it will just be ignored.
        try:
            reaction, user = await self.bot.wait_for("reaction_add", check=reaction_check, timeout=86400)
        except asyncio.TimeoutError:
            ignored_embed = discord.Embed(description=f"Your submission for the part **{part}** has expired.",
                                          colour=green)
            await ctx.author.send(embed=ignored_embed)
            await db.add(ctx.author.id, "ignored")

            # Delete submission from database (in case the bot restarted)
            async with aiosqlite.connect(self.bot.db_path) as conn:
                await conn.execute("DELETE FROM submission_tracking WHERE submission_id = ?", (submission_id,))
                await conn.commit()

            verification_message_embed.colour = grey
            await verification_message.edit(embed=verification_message_embed)
            return

        if reaction.emoji == "✅":
            part_id = await db.add_part(part_data)

            approved_embed = discord.Embed(
                description=f"Your submission for the part **{part}** (ID :`{part_id}`) has been approved. Thank you for contributing!",
                colour=green
            )
            await ctx.author.send(embed=approved_embed)
            await db.add(ctx.author.id, "approved")

            # Delete submission from database (in case the bot restarted)
            async with aiosqlite.connect(self.bot.db_path) as conn:
                await conn.execute("DELETE FROM submission_tracking WHERE submission_id = ?", (submission_id,))
                await conn.commit()

            verification_message_embed.colour = grey
            await verification_message.edit(embed=verification_message_embed)
        elif reaction.emoji == "❌":
            declined_embed = discord.Embed(
                description=f"Your submission for the part **{part}** has been declined.", colour=green
            )
            await ctx.author.send(embed=declined_embed)
            await db.add(ctx.author.id, "declined")

            # Delete submission from database (in case the bot restarted)
            async with aiosqlite.connect(self.bot.db_path) as conn:
                await conn.execute("DELETE FROM submission_tracking WHERE submission_id = ?", (submission_id,))
                await conn.commit()

            verification_message_embed.colour = grey
            await verification_message.edit(embed=verification_message_embed)