Beispiel #1
0
 async def send(self) -> str:
     if self.block_hash is not None:
         return self.block_hash
     elif self.destination is None:
         return
     # Make transaction internal
     resp = await RPCClient.instance().send(id=str(self.id),
                                            source=await
                                            self.sending_user.get_address(),
                                            destination=self.destination,
                                            amount=self.amount)
     if resp is not None:
         async with in_transaction() as conn:
             self.block_hash = resp
             await self.save(using_db=conn)
     return resp
Beispiel #2
0
 async def create_or_fetch_user(cls, user: discord.User) -> 'User':
     """Create a user if they don't exist, raises OperationalError if database error occurs"""
     dbuser: '******' = await cls.filter(
         id=user.id).prefetch_related('account').first()
     if dbuser is None:
         async with in_transaction() as conn:
             # Create user and return them
             dbuser = User(id=user.id, name=user.name.replace("`", ""))
             await dbuser.save(using_db=conn)
             # Create an account
             address = await RPCClient.instance().account_create()
             if address is None:
                 raise Exception("RPC account create failed")
             account = acct.Account(user=dbuser, address=address)
             await account.save(using_db=conn)
     return dbuser
Beispiel #3
0
    async def test_update_await_across_transaction_fail(self):
        obj = await Tournament.create(name="Test1")

        query = Tournament.filter(id=obj.id).update(name="Test2")
        try:
            async with in_transaction():
                await query
                raise KeyError("moo")
        except KeyError:
            pass

        self.assertEqual(await Tournament.all().values("id", "name"),
                         [{
                             "id": obj.id,
                             "name": "Test1"
                         }])
Beispiel #4
0
 async def create_transaction_internal_dbuser(
                             sending_user: usr.User,
                             amount: float,
                             receiving_user: usr.User) -> 'Transaction':
     """Create a transaction in the database, among discord users"""
     # Create transaction
     tx = None
     async with in_transaction() as conn:
         tx = Transaction(
             sending_user = sending_user,
             amount = str(Env.amount_to_raw(amount)),
             destination = await receiving_user.get_address(),
             receiving_user = receiving_user
         )
         await tx.save(using_db=conn)
     return tx
Beispiel #5
0
    async def increasetips_cmd(self, ctx: Context):
        if ctx.error:
            return

        msg = ctx.message

        increasetip_ids = []
        # Get mentioned users
        for m in msg.mentions:
            increasetip_ids.append(m.id)

        # remove duplicates and avoid admins
        increasetip_ids = set(increasetip_ids)
        increasetip_ids = [x for x in increasetip_ids if x not in config.Config.instance().get_admin_ids()]
        if msg.author.id not in config.Config.instance().get_admin_ids():
            for d in increasetip_ids:
                memba = msg.guild.get_member(d)
                if memba is not None:
                    for r in memba.roles:
                        if r.id in [config.Config.instance().get_admin_roles()]:
                            d.remove(r.id)


        if len(increasetip_ids) < 1:
            await Messages.add_x_reaction(msg)
            await msg.author.send("Your message has no users to increasetips for")
            return

        try:
            amount = RegexUtil.find_float(msg.content)
        except AmountMissingException:
            await Messages.send_usage_dm(msg.author, INCREASETIPS_INFO)
            return

        # TODO - tortoise doesnt give us any feedback on update counts atm
        # https://github.com/tortoise/tortoise-orm/issues/126
        # TODO - we also don't have atomic updates :/
        increase_tip_count = 0
        for u in await Stats.filter(user_id__in=increasetip_ids, server_id=msg.guild.id).all():
            async with in_transaction() as conn:
                u.total_tipped_amount = float(u.total_tipped_amount) + amount
                u.legacy_total_tipped_amount = float(u.legacy_total_tipped_amount) + amount
                await u.save(using_db=conn, update_fields=['total_tipped_amount', 'legacy_total_tipped_amount'])
                increase_tip_count += 1

        await msg.author.send(f"Increased stats of {increase_tip_count} by {amount} {Env.currency_name()}")
        await msg.add_reaction("\u2795")
    async def post(self, username: str, password: str):
        """
        Authenticate user.
        Example API data: {
            "username": "******",
            "password": "******"
            }
        :param username: user's username
        :param password:  user's password
        :return: {
                    'id': _users_id_,
                    'token': _jwt_authorization_token_
                }
        """
        async with in_transaction(base.config.conf['name']):
            username = username.lower().strip()
            user = await models.users.AuthUser.filter(username=username).get_or_none()
            if not user:
                log.error(f'User with username {user} do not exists')
                raise base.http.HttpErrorUnauthorized

            if not user.active:
                log.error(f'User {username} is not an active user and can not be authenticated')
                raise base.http.HttpErrorUnauthorized

            if not password_match(username, password, user.password):
                log.error(f'Password for user {username} -> {password} not match')
                raise base.http.HttpErrorUnauthorized

            _session = await models.session.Session.filter(user=user, active=True).get_or_none()
            if not _session:
                _session = models.session.Session(user=user)
                await _session.save()

            _user_data = await user.serialize(all_data=True)
            await set_user_session_to_store(_user_data, _session)

        token = await _session.token
        dummy_request = DummyRequest()
        dummy_request.headers[base.config.conf['authorization']['key']] = token
        profile_image = await self.get_profile_image(user.id, dummy_request)

        return {'id': str(user.id),
                'token': token,
                'profile_image': profile_image
                
                }, base.http.status.CREATED
Beispiel #7
0
async def runtest(loopstr):
    inrange = 10 // concurrents
    if inrange < 1:
        inrange = 1

    objs = list(await Journal.all())
    count = len(objs)

    start = now = time.time()

    async with in_transaction():
        for obj in objs:
            await obj.delete()

    now = time.time()

    print(f'Tortoise ORM{loopstr}, K: Rows/sec: {count / (now - start): 10.2f}')
Beispiel #8
0
async def wallet_change_seed(wallet_id: str, seed: str, password: str) -> str:
    encrypt = False
    old_password = None
    if len(password) > 0:
        encrypt = True

    # Retrieve wallet
    try:
        wallet = await Wallet.get_wallet(wallet_id)
    except WalletNotFound:
        print(f"No wallet found with ID: {wallet_id}")
        exit(1)
    except WalletLocked as wl:
        wallet = wl.wallet
        while True:
            try:
                npass = getpass.getpass(prompt='Enter current password:'******'seed', 'encrypted'])
                        for a in await wallet.adhoc_accounts.all():
                            a.private_key = crypt.decrypt(a.private_key)
                            await a.save(using_db=conn, update_fields=['private_key'])
                    old_password = npass
                    break
                except DecryptionError:
                    print("**Invalid password**")
            except KeyboardInterrupt:
                break
                exit(0)

    # Change key
    await wallet.change_seed(seed)

    # Encrypt if necessary
    if encrypt:
        await wallet.encrypt_wallet(password)

    # Get newest account
    newest = await wallet.get_newest_account()

    print(f"Seed changed for wallet {wallet.id}\nFirst account: {newest.address}")
Beispiel #9
0
async def create_users():
    # # Generate random email
    # with open('/usr/share/dict/cracklib-small', 'r') as w:
    #     words = w.read().splitlines()
    # random_word = random.choice(words)
    # host = random.choice(['gmail', 'yahoo', 'amazon', 'yahoo', 'microsoft', 'google'])
    # tld = random.choice(['org', 'com', 'net', 'io', 'com.ph', 'co.uk'])
    # email = f'{random_word}@{host}.{tld}'
    # from app.auth import userdb

    async with in_transaction():
        # User 1
        userdata = UserCreate(email=EmailStr(VERIFIED_EMAIL_DEMO),
                              password='******')
        create_user = get_create_user(userdb, UserDB)
        created_user = await create_user(userdata, safe=True)
        ret = created_user
        groups = await Group.filter(name__in=s.USER_GROUPS)

        user = await UserMod.get(pk=created_user.id)
        user.is_verified = True
        user.is_superuser = True
        await user.save()
        await user.groups.add(*groups)

        # Perms for User 1
        ll = []
        userperms = await Permission.filter(code__in=enchance_only_perms
                                            ).only('id')
        for perm in userperms:
            ll.append(UserPermissions(user=user, permission=perm, author=user))
        await UserPermissions.bulk_create(ll)

        # Group or User 1
        # await user.add_group('StaffGroup')

        # User 2
        userdata = UserCreate(email=EmailStr(UNVERIFIED_EMAIL_DEMO),
                              password='******')
        create_user = get_create_user(userdb, UserDB)
        created_user = await create_user(userdata, safe=True)
        groups = await Group.filter(name__in=s.USER_GROUPS)
        user = await UserMod.get(pk=created_user.id)
        await user.groups.add(*groups)

        return ret
Beispiel #10
0
async def update(
        request: Request,
        resource: str = Path(...),
        pk: int = Path(...),
        model_resource: ModelResource = Depends(get_model_resource),
        resources=Depends(get_resources),
        model=Depends(get_model),
):
    form = await request.form()
    data, m2m_data = await model_resource.resolve_data(request, form)
    async with in_transaction() as conn:
        obj = (await model.filter(
            pk=pk).using_db(conn).select_for_update().get().prefetch_related(
                *model_resource.get_m2m_field()))
        await obj.update_from_dict(data).save(using_db=conn)
        for k, items in m2m_data.items():
            m2m_obj = getattr(obj, k)
            await m2m_obj.clear()
            if items:
                await m2m_obj.add(*items)
        obj = (await model.filter(pk=pk).using_db(conn).get().prefetch_related(
            *model_resource.get_m2m_field()))
    inputs = await model_resource.get_inputs(obj)
    if "save" in form.keys():
        context = {
            "request": request,
            "resources": resources,
            "resource_label": model_resource.label,
            "resource": resource,
            "model_resource": model_resource,
            "inputs": inputs,
            "pk": pk,
            "page_title": model_resource.page_title,
            "page_pre_title": model_resource.page_pre_title,
        }
        try:
            return templates.TemplateResponse(
                f"{resource}/update.html",
                context=context,
            )
        except TemplateNotFound:
            return templates.TemplateResponse(
                "update.html",
                context=context,
            )
    return redirect(request, "list_view", resource=resource)
async def upload_words_pairs(upload_words_pairs_request: UploadWordsPairsRequest):
    inserting_date = datetime.now()
    with open(upload_words_pairs_request.filename, newline='') as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',', quotechar='|')
        objects_list = []
        for from_language, to_language, from_word, to_word in csv_reader:
            objects_list.append(SavedWord(from_language=from_language, to_language=to_language, from_word=from_word,
                                          to_word=to_word, words_group_name=upload_words_pairs_request.filename,
                                          cdate=inserting_date))
    async with in_transaction():
        try:
            await SavedWord.filter(words_group_name=upload_words_pairs_request.filename).delete()
            await SavedWord.bulk_create(objects_list, batch_size=100)
        except OperationalError as e:
            return {'ok': False, 'errors': [str(e), ]}

    return {'ok': True, 'errors': []}
Beispiel #12
0
async def debit(request: Request) -> UJSONResponse:
    business_wallet_id = request.path_params["wallet_id"]

    try:
        payload = await request.json()
        customer_wallet_id = payload.pop("customer_wallet_id")

        # check wallets existence
        business_wallet = await BusinessWallet.get_or_none(
            id=business_wallet_id)
        customer_wallet = await CustomerWallet.get_or_none(
            id=customer_wallet_id)
        if not business_wallet:
            raise HTTPException(
                status_code=404,
                detail=f"There is no wallet with id {business_wallet_id}",
            )
        if not customer_wallet:
            raise HTTPException(
                status_code=404,
                detail=
                f"There is no customer wallet with id {customer_wallet_id}",
            )

        transaction_data = InputDebitTransactionSchema.parse_obj(payload)

        async with in_transaction() as connection:
            transaction = await DebitTransaction.create(
                **transaction_data.dict(),
                customer_wallet_id=customer_wallet_id,
                business_wallet_id=business_wallet_id,
                using_db=connection,
            )
            if transaction.status == TransactionStatus.DENIED:
                raise UnexpectedError(transaction.error)
    except JSONDecodeError:
        raise HTTPException(status_code=400, detail=MALFORMED_JSON_MESSAGE)
    except (AmountMustBeAPositiveNumber, NotEnoughBalance, OperationalError,
            UnexpectedError) as e:
        raise HTTPException(status_code=409, detail=str(e))

    response = OutputDebitTransactionSchema.from_orm(transaction)
    response = loads(response.json())
    response["id"] = str(transaction.id)
    return UJSONResponse(response, status_code=HTTP_201_CREATED)
Beispiel #13
0
async def article_update(pk, data: ArticleCreateRequest):
    async with in_transaction():
        if not await Category.filter(id=data.category_id).exists():
            raise ClientError.BadRequest400(
                f"category_id({data.category_id}) not exist")
        for tag_id in data.tags:
            if not await Tag.filter(id=tag_id).exists():
                raise ClientError.BadRequest400(f"tag_id({tag_id}) not exist")
        tags = data.tags
        article__kwargs = data.dict()
        del article__kwargs['tags']
        instance = await Article.get(id=pk)
        instance.update_from_dict(article__kwargs)
        await instance.save()
        await instance.tags.clear()
        await instance.tags.add(
            *[await Tag.get(id=tag_id) for tag_id in list(set(tags))])
    return await ArticleCreateResponse.from_tortoise_orm(instance)
    async def accounts_create(self, request: web.Request, request_json: dict):
        """Route for creating new wallet"""
        if 'wallet' not in request_json or 'count' not in request_json or not isinstance(
                request_json['count'], int):
            return self.generic_error()

        try:
            wallet = await Wallet.get_wallet(request_json['wallet'])
        except WalletNotFound:
            return self.json_response(data={'error': 'wallet not found'})
        except WalletLocked:
            return self.json_response(data={'error': 'wallet locked'})

        # Create account
        async with in_transaction() as conn:
            accounts = await wallet.accounts_create(
                count=request_json['count'], using_db=conn)
        return self.json_response(data={'accounts': accounts})
Beispiel #15
0
async def question_delete(request):
    """
    Delete question
    """
    id = request.path_params["id"]
    if request.method == "POST":
        # delete all related tags
        async with in_transaction() as conn:
            await conn.execute_query(
                f"DELETE FROM tag WHERE tag.id IN \
                (SELECT question_tag.tag_id FROM question \
                JOIN question_tag ON question_tag.question_id = question.id \
                WHERE question.id={id})"
            )
        await Question.get(id=id).delete()
        if request.user.username == ADMIN:
            return RedirectResponse(url="/accounts/dashboard", status_code=302)
        return RedirectResponse(url="/accounts/profile", status_code=302)
Beispiel #16
0
async def upgrade(ctx: Context):
    config = ctx.obj["config"]
    app = ctx.obj["app"]
    migrated = False
    for version in Migrate.get_all_version_files():
        if not await Aerich.exists(version=version, app=app):
            async with in_transaction(get_app_connection_name(config, app)) as conn:
                file_path = os.path.join(Migrate.migrate_location, version)
                with open(file_path, "r") as f:
                    content = json.load(f)
                    upgrade_query_list = content.get("upgrade")
                    for upgrade_query in upgrade_query_list:
                        await conn.execute_query(upgrade_query)
            await Aerich.create(version=version, app=app)
            click.secho(f"Success upgrade {version}", fg=Color.green)
            migrated = True
    if not migrated:
        click.secho("No migrate items", fg=Color.yellow)
Beispiel #17
0
async def downgrade(ctx: Context):
    app = ctx.obj["app"]
    config = ctx.obj["config"]
    last_version = await Migrate.get_last_version()
    if not last_version:
        return click.secho("No last version found", fg=Color.yellow)
    file = last_version.version
    async with in_transaction(get_app_connection_name(config, app)) as conn:
        file_path = os.path.join(Migrate.migrate_location, file)
        with open(file_path, "r") as f:
            content = json.load(f)
            downgrade_query_list = content.get("downgrade")
            if not downgrade_query_list:
                return click.secho(f"No downgrade item dound", fg=Color.yellow)
            for downgrade_query in downgrade_query_list:
                await conn.execute_query(downgrade_query)
            await last_version.delete()
        return click.secho(f"Success downgrade {file}", fg=Color.green)
Beispiel #18
0
async def downgrade(ctx: Context):
    """Downgrade to previous version."""
    app, config, location = await connect_tortoise(ctx)
    last_version = await Migrate.get_last_version()
    if not last_version:
        return typer.secho("No last version found", fg=typer.colors.YELLOW)
    file = last_version.version
    async with in_transaction(get_app_connection_name(config, app)) as conn:
        file_path = os.path.join(Migrate.migrate_location, file)
        with open(file_path, "r", encoding="utf-8") as f:
            content = json.load(f)
            downgrade_query_list = content.get("downgrade")
            if not downgrade_query_list:
                return typer.secho("No downgrade item found", fg=typer.colors.YELLOW)
            for downgrade_query in downgrade_query_list:
                await conn.execute_query(downgrade_query)
            await last_version.delete()
        return typer.secho(f"Success downgrade {file}", fg=typer.colors.GREEN)
Beispiel #19
0
 async def lottery_status_cron_job(self):
     with Hub(Hub.current):
         # ensure that only one instance of job is running, other instances will be discarded
         if not self.lock.locked():
             await self.lock.acquire()
             try:
                 should_reload_options = False
                 async with in_transaction():
                     await self._handle_stopping_sales()
                     await self._handle_selecting_winning_tickets()
                     should_reload_options = await self._handle_payments_to_winners()
                 if should_reload_options:
                     await reload_options_hack(self.bot)
             except Exception as e:
                 logging.debug(f":::lottery_cron: {e}")
                 capture_exception(e)
             finally:
                 self.lock.release()
Beispiel #20
0
 async def get_address(self) -> str:
     """Get account address of user"""
     if isinstance(self.account, acct.Account):
         return self.account.address
     account = await self.account.first()
     if account is not None:
         return account.address
     # Create an account
     address = await RPCClient.instance().account_create()
     if address is None:
         raise Exception("RPC account create failed")
     account = acct.Account(
         user = self,
         address = address
     )
     async with in_transaction() as conn:
         await account.save(using_db=conn)
     return address
Beispiel #21
0
 async def create_transaction_internal(
         sending_user: usr.User, amount: float,
         receiving_user: discord.User) -> 'Transaction':
     """Create a transaction in the database, among discord users"""
     # See if receiving user exists in our database
     receiving_user_db: usr.User = await usr.User.create_or_fetch_user(
         receiving_user)
     if receiving_user_db.tip_banned:
         return None
     # Create transaction
     tx = None
     async with in_transaction() as conn:
         tx = Transaction(sending_user=sending_user,
                          amount=str(Env.amount_to_raw(amount)),
                          destination=await receiving_user_db.get_address(),
                          receiving_user=receiving_user_db)
         await tx.save(using_db=conn)
     return tx
Beispiel #22
0
async def runtest(loopstr):
    inrange = 10 // concurrents
    if inrange < 1:
        inrange = 1

    objs = list(await Journal.all())
    count = len(objs)

    start = now = time.time()

    async with in_transaction():
        for obj in objs:
            obj.level = choice(LEVEL_CHOICE)
            await obj.save(update_fields=["level"])

    now = time.time()

    print(f'Tortoise ORM{loopstr}, J: Rows/sec: {count / (now - start): 10.2f}')
Beispiel #23
0
async def question_delete(request):
    """
    Delete question
    """
    id = request.path_params["id"]
    session_user = request.user.username
    results = await Question.get(id=id).prefetch_related('user')
    if request.method == "DELETE" and results.user.username == session_user:
        async with in_transaction() as conn:
            await conn.execute_query(f"DELETE FROM tag WHERE tag.id IN \
                (SELECT question_tag.tag_id FROM question \
                JOIN question_tag \
                ON question_tag.question_id = question.id \
                WHERE question.id={id})")
        await Question.get(id=id).delete()
        # 303 status code for redirect after delete
        response = RedirectResponse(url="/", status_code=303)
        return response
Beispiel #24
0
async def upgrade(ctx: Context):
    app = ctx.obj["app"]
    config = ctx.obj["config"]
    available_versions = Migrate.get_all_version_files(is_all=False)
    if not available_versions:
        return click.secho("No migrate items", fg=Color.yellow)
    async with in_transaction(get_app_connection_name(config, app)) as conn:
        for file in available_versions:
            file_path = os.path.join(Migrate.migrate_location, file)
            with open(file_path, "r") as f:
                content = json.load(f)
                upgrade_query_list = content.get("upgrade")
                for upgrade_query in upgrade_query_list:
                    await conn.execute_query(upgrade_query)

            with open(file_path, "w") as f:
                content["migrate"] = True
                json.dump(content, f, indent=2, ensure_ascii=False)
                click.secho(f"Success upgrade {file}", fg=Color.green)
Beispiel #25
0
async def random_businesses(request):
    async def fin():
        async with in_transaction() as connection:
            for business in businesses_db:
                await business.delete(using_db=connection)

    businesses_db = []
    businesses = []
    request.addfinalizer(fin)

    async with in_transaction() as connection:
        for _ in range(request.param):
            business_data = business_data()
            business = Customer(**asdict(business_data))
            await business.save(using_db=connection)
            businesses_db.append(business)
            businesses.append(OutputBusinessSchema.from_orm(business).dict())

    yield businesses_db, businesses
Beispiel #26
0
async def random_customers(request):
    async def fin():
        async with in_transaction() as connection:
            for customer in customers_db:
                await customer.delete(using_db=connection)

    customers_db = []
    customers = []
    request.addfinalizer(fin)

    async with in_transaction() as connection:
        for _ in range(request.param):
            customer_data = customer_data()
            customer = Customer(**asdict(customer_data))
            await customer.save(using_db=connection)
            customers_db.append(customer)
            customers.append(OutputCustomerSchema.from_orm(customer).dict())

    yield customers_db, customers
Beispiel #27
0
async def random_users(request):
    async def fin():
        async with in_transaction() as connection:
            for user in users_db:
                await user.delete(using_db=connection)

    users_db = []
    users = []
    request.addfinalizer(fin)

    async with in_transaction() as connection:
        for _ in range(request.param):
            user_d = user_data()
            user = User(**asdict(user_d))
            await user.save(using_db=connection)
            users_db.append(user)
            users.append(asdict(user_d))

    yield users_db, users
Beispiel #28
0
async def add_spenses_for_user(id_user:uuid.UUID, spenses:list):

    async with in_transaction('models'):
    
      user = await User.filter(id=id_user).get_or_none()
      if not user:
          return {'status': 'error', 'message': 'not-found'}

      for t in spenses:
        db_t = Trosak(user=user, name=t['name'], price=t['price'])
        user.monthly_income -= t['price']
        await user.save()
        if user.monthly_income < 0:
            raise NameError("nema para na racunu")
            
        await db_t.save()

    
    return {'status': 'ok'}
Beispiel #29
0
async def cancel_karma_change(karma_event_id: int, rollback_karma: int,
                              moderator_event_id: int, bot: Bot):
    async with in_transaction() as conn:
        karma_event = await KarmaEvent.get(id_=karma_event_id)

        # noinspection PyUnresolvedReferences
        user_to_id = karma_event.user_to_id
        # noinspection PyUnresolvedReferences
        user_from_id = karma_event.user_from_id
        # noinspection PyUnresolvedReferences
        chat_id = karma_event.chat_id

        user_karma = await UserKarma.get(chat_id=chat_id, user_id=user_to_id)
        user_karma.karma = user_karma.karma + rollback_karma
        await user_karma.save(update_fields=['karma'], using_db=conn)
        await karma_event.delete(using_db=conn)
        if moderator_event_id is not None:
            moderator_event = await ModeratorEvent.get(id_=moderator_event_id)
            restricted_user = await User.get(id=user_to_id)

            if moderator_event.type_restriction == TypeRestriction.karmic_ro.name:
                await bot.restrict_chat_member(
                    chat_id=chat_id,
                    user_id=restricted_user.tg_id,
                    can_send_messages=True,
                    can_send_media_messages=True,
                    can_add_web_page_previews=True,
                    can_send_other_messages=True,
                )

            elif moderator_event.type_restriction == TypeRestriction.karmic_ban.name:
                await bot.unban_chat_member(chat_id=chat_id,
                                            user_id=restricted_user.tg_id,
                                            only_if_banned=True)

            await moderator_event.delete(using_db=conn)

        logger.info(
            "user {user} cancel change karma to user {target} in chat {chat}",
            user=user_from_id,
            target=user_to_id,
            chat=chat_id)
Beispiel #30
0
async def insert_message(message):
    # if message.id not in recent_list and message.id not in previous_list:
    message_type = message.type
    if message_type == MessageType.default:
        message_type = None
    else:
        if not isinstance(message_type, int):
            message_type = message_type.value
    #     m = fakeLoggedMessage(messageid=message.id, content=message.content,
    #                           author=message.author.id,
    #                           channel=message.channel.id, server=message.guild.id,
    #                           type=message_type, pinned=message.pinned, attachments=[LoggedAttachment(id=a.id, name=a.filename,
    #                                                                                        isImage=(a.width is not None or a.width is 0),
    #                                                                                        message_id=message.id) for a in message.attachments])
    #     batch[message.id] = m
    #
    #     recent_list.add(message.id)
    #     if len(batch) >= 1000:
    #         asyncio.create_task(flush(force=True))

    try:
        async with in_transaction():
            is_reply = message.reference is not None and message.reference.channel_id == message.channel.id
            logged = await LoggedMessage.create(
                messageid=message.id,
                content=message.content.replace('\x00', ''),
                author=message.author.id,
                channel=message.channel.id,
                server=message.guild.id,
                type=message_type,
                pinned=message.pinned,
                reply_to=message.reference.message_id if is_reply else None)
        for a in message.attachments:
            await LoggedAttachment.create(id=a.id,
                                          name=a.filename,
                                          isImage=(a.width is not None
                                                   or a.width == 0),
                                          message=logged)

    except IntegrityError:
        return message
    return message