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
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
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" }])
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
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
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}')
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}")
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
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': []}
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)
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})
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)
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)
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)
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)
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()
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
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
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}')
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
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)
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
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
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
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'}
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)
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