def create_sell_lot(context): if not all(card.available_for_auction for card in context.cards): raise dext_views.ViewError(code='not_available_for_auction', message='Как минимум одна из карт не может быть продана на аукционе') for card in context.cards: if context.price < relations.CARDS_MIN_PRICES[card.type.rarity]: raise dext_views.ViewError(code='too_small_price', message='Цена продажи меньше чем минимально разрешённая цена продажи как минимум одной карты') lots = [] for card in context.cards: lots.append(objects.Lot(owner_id=context.account.id, full_type=card.item_full_type, item_id=card.uid, price=context.price)) cards_tt_api.change_cards_owner(old_owner_id=context.account.id, new_owner_id=accounts_logic.get_system_user_id(), operation_type='#create_sell_lots', new_storage=cards_relations.STORAGE.FAST, cards_ids=[card.uid for card in context.cards]) tt_api.place_sell_lots(lots) return dext_views.AjaxOk()
def preprocess(self, context): api_version = context.django_request.GET.get('api_version', '').strip() if not api_version: raise dext_views.ViewError(code='api.no_method_version', message='Не указана версия метода') if api_version not in self.versions: raise dext_views.ViewError( code='api.wrong_method_version', message='Неверная версия метода, ожидается одна из: %s' % ', '.join(self.versions)) context.api_version = api_version api_client = context.django_request.GET.get('api_client', '').strip() if not api_client: raise dext_views.ViewError(code='api.no_client_identificator', message='Не указана версия клиента') if not check_client_version(api_client): raise dext_views.ViewError( code='api.wrong_client_identificator_format', message= 'Неверный идентификатор клиента, ожидается <название программы>-<версия программы>' ) context.api_client = api_client
def check_recipients(recipients_form): system_user = accounts_logic.get_system_user() if system_user.id in recipients_form.c.recipients: raise dext_views.ViewError(code='system_user', message='Нельзя отправить сообщение системному пользователю') if accounts_models.Account.objects.filter(is_fast=True, id__in=recipients_form.c.recipients).exists(): raise dext_views.ViewError(code='fast_account', message='Нельзя отправить сообщение пользователю, не завершившему регистрацию') if accounts_models.Account.objects.filter(id__in=recipients_form.c.recipients).count() != len(recipients_form.c.recipients): raise dext_views.ViewError(code='unexisted_account', message='Вы пытаетесь отправить сообщение несуществующему пользователю')
def transfer_money(context): if context.account.id == context.master_account.id: raise dext_views.ViewError(code='own_account', message=u'Нельзя переводить печеньки самому себе') if context.form.c.money > context.account.bank_account.amount: raise dext_views.ViewError(code='not_enough_money', message=u'Недостаточно печенек для перевода') task = logic.initiate_transfer_money(sender_id=context.account.id, recipient_id=context.master_account.id, amount=context.form.c.money, comment=context.form.c.comment) return dext_views.AjaxProcessing(task.status_url)
def fast_post(context): if context.account.is_authenticated: raise dext_views.ViewError(code='accounts.registration.fast.already_registered', message='Вы уже зарегистрированы') task = create_registration_task(context.django_request.session) if task.state.is_processed: raise dext_views.ViewError(code='accounts.registration.fast.already_processed', message='Вы уже зарегистрированы, обновите страницу') return dext_views.AjaxProcessing(task.status_url)
def api_combine(context): card, result = logic.get_combined_card( allow_premium_cards=context.account.is_premium, combined_cards=context.cards) if not result.is_SUCCESS: raise dext_views.ViewError(code='wrong_cards', message=result.text) try: tt_api.change_cards(account_id=context.account.id, operation_type='combine-cards', to_add=[card], to_remove=context.cards) except utils_exceptions.TTAPIUnexpectedAPIStatus: # return error, in most cases it is duplicate request raise dext_views.ViewError( code='can_not_combine_cards', message= 'Не удалось объединить карты. Попробуйте обновить страницу и повторить попытку.' ) ################################## # change combined cards statistics logic_task = heroes_postponed_tasks.InvokeHeroMethodTask( hero_id=context.account.id, method_name='new_cards_combined', method_kwargs={'number': 1}) task = PostponedTaskPrototype.create(logic_task) amqp_environment.environment.workers.supervisor.cmd_logic_task( account_id=context.account.id, task_id=task.id) ################################## MESSAGE = ''' <p>Вы получаете новую карту: <span class="%(rarity)s-card-label">%(name)s</span><br/><br/></p> <blockquote>%(description)s</blockquote> ''' message = MESSAGE % { 'name': card.name[0].upper() + card.name[1:], 'description': card.effect.DESCRIPTION, 'rarity': card.type.rarity.name.lower() } return dext_views.AjaxOk(content={ 'message': message, 'card': card.ui_info() })
def new(context): text = u'' if context.answer_to: if context.answer_to.recipient_id != context.account.id: raise dext_views.ViewError( code='no_permissions_to_answer_to', message=u'Вы пытаетесь ответить на чужое сообщение') text = u'[quote]\n%s\n[/quote]\n' % context.answer_to.text check_recipients(context.form) form = forms.NewMessageForm( initial={ 'text': text, 'recipients': ','.join( str(recipient_id) for recipient_id in context.form.c.recipients) }) return dext_views.Page( 'personal_messages/new.html', content={ 'recipients': accounts_prototypes.AccountPrototype.get_list_by_id( context.form.c.recipients), 'form': form, 'resource': context.resource })
def api_use(context): u''' Использовать карту из колоды игрока. - **адрес:** /game/cards/api/use - **http-метод:** POST - **версии:** 1.0 - **параметры:** * GET: card — уникальный идентификатор карты в калоде * POST: person — идентификатор Мастера, если карта применяется к Мастеру * POST: place — идентификатор города, если карта применяется к городу * POST: building — идентификатор здания, если карта применяется к зданию - **возможные ошибки**: * cards.use.form_errors — ошибка в одном из POST параметров Метод является «неблокирующей операцией» (см. документацию), формат ответа соответствует ответу для всех «неблокирующих операций». ''' form = context.account_card.type.form(context.django_request.POST) if not form.is_valid(): raise dext_views.ViewError(code=u'form_errors', message=form.errors) task = context.account_card.activate(context.account_hero, data=form.get_card_data()) return dext_views.AjaxProcessing(task.status_url)
def preprocess(self, context): context.django_superuser = context.account.is_superuser if not context.django_superuser: raise dext_views.ViewError( code='common.superuser_required', message='У Вас нет прав для проведения данной операции')
def region(context): ''' Карта мира на указанный (или последний) ход. Версия карты есть не для каждого хода. Получить список ходов, для которых есть созхранённая карта, можно отдельным запросом. - **адрес:** /game/map/api/region - **http-метод:** GET - **версии:** 0.1 - **параметры:** * GET: turn - целое, номер хода, на который необходимо получить карту - **возможные ошибки**: * no_region_found - для заданного хода нет сохранённых данных Стабильность формата данных в ответе не гарантируется. ''' if context.turn is None: region = models.MapRegion.objects.latest('created_at') else: try: region = models.MapRegion.objects.get(turn_number=context.turn) except models.MapRegion.DoesNotExist: raise dext_views.ViewError( code='no_region_found', message='Описание карты для заданного хода не найдено') return dext_views.AjaxOk(content={ 'region': region.data, 'turn': region.turn_number })
def transfer_money_dialog(context): if context.account.id == context.master_account.id: raise dext_views.ViewError(code='own_account', message=u'Нельзя переводить печеньки самому себе') return dext_views.Page('accounts/transfer_money.html', content={'commission': conf.accounts_settings.MONEY_SEND_COMMISSION, 'form': forms.SendMoneyForm()} )
def show(context): if context.companion.state.is_DISABLED and not ( context.companions_can_edit or context.companions_can_moderate): raise dext_views.ViewError( code='no_rights', message='Вы не можете просматривать информацию по данному спутнику.' ) template_restriction, ingame_companion_phrases = logic.required_templates_count( context.companion) return dext_views.Page('companions/show.html', content={ 'context': context, 'companion_meta_object': meta_relations.Companion.create_from_object( context.companion), 'resource': context.resource, 'companion': context.companion, 'ingame_companion_phrases': ingame_companion_phrases, 'template_restriction': template_restriction, 'section': 'companions' })
def take_card_callback(context): account = accounts_prototypes.AccountPrototype.get_by_id( context.tt_request.timer.owner_id) if account is None: return dext_views.AjaxOk() if not logic_checkers.is_player_participate_in_game( is_banned=account.is_ban_game, active_end_at=account.active_end_at, is_premium=account.is_premium): raise dext_views.ViewError( code='common.player_does_not_participate_in_game', message='игрок не активен, карты ему не выдаются') expected_speed = logic_cards_constants.NORMAL_PLAYER_SPEED if account.is_premium: expected_speed = logic_cards_constants.PREMIUM_PLAYER_SPEED if context.tt_request.timer.speed != expected_speed: accounts_tt_api.change_cards_timer_speed(account_id=account.id, speed=expected_speed) logic.give_new_cards(account_id=account.id, operation_type='give-card', allow_premium_cards=account.is_premium, available_for_auction=account.is_premium) return dext_views.AjaxOk()
def preprocess(self, context): if third_party_settings.ACCESS_TOKEN_SESSION_KEY in context.django_request.session: raise dext_views.ViewError( code='third_party.access_restricted', message= 'Доступ к этой функциональности запрещён для сторонних приложений' )
def show_dialog(context): if context.companion.state.is_DISABLED and not (context.companions_can_edit or context.companions_can_moderate): raise dext_views.ViewError(code='no_rights', message=u'Вы не можете просматривать информацию по данному спутнику.') return dext_views.Page('companions/info.html', content={'companion': context.companion, 'companion_meta_object': meta_relations.Companion.create_from_object(context.companion), 'resource': context.resource})
def delete(context): if context.account.id not in (context.message.sender_id, context.message.recipient_id): raise dext_views.ViewError(code='no_permissions', message='Вы не можете влиять на это сообщение') context.message.hide_from(sender=(context.account.id == context.message.sender_id), recipient=(context.account.id == context.message.recipient_id)) return dext_views.AjaxOk()
def preprocess(self, context): try: context.tt_request = self.request_class.FromString( context.django_request.body) except: raise dext_views.ViewError( code='common.wrong_tt_post_data', message='Переданы неверные данные', http_status=dext_relations.HTTP_STATUS.INTERNAL_SERVER_ERROR)
def api_names(context): if context.names_number < 0 or 100 < context.names_number: raise dext_views.ViewError( code='wrong_number', message='Нельзя сгенерировать такое колдичесво имён') result_names = names.get_names_set(number=context.names_number) return dext_views.AjaxOk(content={'names': result_names})
def delete(context): owners_ids = [context.message.sender_id] owners_ids.extend(context.message.recipients_ids) if context.account.id not in owners_ids: raise dext_views.ViewError(code='no_permissions', message='Вы не можете влиять на это сообщение') tt_api.hide_message(account_id=context.account.id, message_id=context.message.id) return dext_views.AjaxOk()
def api_use(context): form = context.account_card.get_form(data=context.django_request.POST, hero=context.account_hero) if not form.is_valid(): raise dext_views.ViewError(code='form_errors', message=form.errors) task = context.account_card.activate(context.account_hero, data=form.get_card_data()) return dext_views.AjaxProcessing(task.status_url)
def give_money(context): if context.target_account.is_fast: raise dext_views.ViewError(code='fast_account', message='Нельзя начислить деньги «быстрому» аккаунту') logic.transaction_gm(account=context.target_account, amount=context.form.c.amount, description=context.form.c.description, game_master=context.account) return dext_views.AjaxOk()
def close_sell_lot(context): if context.account.bank_account.amount < context.price: raise dext_views.ViewError(code='not_enough_money', message='Не хватает средств для покупки') task = logic.close_lot(item_type=context.item_type, price=context.price, buyer_id=context.account.id) postponed_task = PostponedTaskPrototype.create(task) postponed_task.cmd_wait() return dext_views.AjaxProcessing(postponed_task.status_url)
def region(context): if context.turn is None: region = models.MapRegion.objects.latest('created_at') else: try: region = models.MapRegion.objects.get(turn_number=context.turn) except models.MapRegion.DoesNotExist: raise dext_views.ViewError( code='no_region_found', message='Описание карты для заданного хода не найдено') return dext_views.AjaxOk(content={ 'region': region.data, 'turn': region.turn_number })
def ban(context): if context.form.c.ban_type.is_FORUM: context.master_account.ban_forum(context.form.c.ban_time.days) message = 'Вы лишены права общаться на форуме. Причина: \n\n%(message)s' elif context.form.c.ban_type.is_GAME: context.master_account.ban_game(context.form.c.ban_time.days) message = 'Ваш герой лишён возможности влиять на мир игры. Причина: \n\n%(message)s' elif context.form.c.ban_type.is_TOTAL: context.master_account.ban_forum(context.form.c.ban_time.days) context.master_account.ban_game(context.form.c.ban_time.days) message = 'Вы лишены права общаться на форуме, ваш герой лишён возможности влиять на мир игры. Причина: \n\n%(message)s' else: raise dext_views.ViewError(code='unknown_ban_type', message='Неизвестный тип бана') pm_tt_api.send_message(sender_id=logic.get_system_user_id(), recipients_ids=[context.master_account.id], body=message % {'message': context.form.c.description}) return dext_views.AjaxOk()
def ban(context): if context.form.c.ban_type.is_FORUM: context.master_account.ban_forum(context.form.c.ban_time.days) message = 'Вы лишены права общаться на форуме. Причина: \n\n%(message)s' elif context.form.c.ban_type.is_GAME: context.master_account.ban_game(context.form.c.ban_time.days) message = 'Ваш герой лишён возможности влиять на мир игры. Причина: \n\n%(message)s' elif context.form.c.ban_type.is_TOTAL: context.master_account.ban_forum(context.form.c.ban_time.days) context.master_account.ban_game(context.form.c.ban_time.days) message = 'Вы лишены права общаться на форуме, ваш герой лишён возможности влиять на мир игры. Причина: \n\n%(message)s' else: raise dext_views.ViewError(code='unknown_ban_type', message='Неизвестный тип бана') MessagePrototype.create(logic.get_system_user(), context.master_account, message % {'message': context.form.c.description}) return dext_views.AjaxOk()
def api_combine(context): u''' Объединить карты из колоды игрока. - **адрес:** /game/cards/api/combine - **http-метод:** POST - **версии:** 1.0 - **параметры:** * GET: cards — перечень уникальный идентификаторов карт в колоде игрока через запятую - **возможные ошибки**: * cards.api-combine.wrong_cards — указанные карты нельзя объединить Метод является «неблокирующей операцией» (см. документацию), формат ответа соответствует ответу для всех «неблокирующих операций». При завершении операции возвращается дополнительная инфрмация: { "message": "строка", // описание результата в формате html "card": <card_info> // описание полученной карты, формат см. в описании формата информации о герое } ''' can_combine_status = context.account_hero.cards.can_combine_cards( [card.uid for card in context.account_cards]) if not can_combine_status.is_ALLOWED: raise dext_views.ViewError(code=u'wrong_cards', message=can_combine_status.text) choose_task = heroes_postponed_tasks.CombineCardsTask( hero_id=context.account_hero.id, cards=[card.uid for card in context.account_cards]) task = PostponedTaskPrototype.create(choose_task) amqp_environment.environment.workers.supervisor.cmd_logic_task( context.account.id, task.id) return dext_views.AjaxProcessing(task.status_url)
def cell_info(context): x, y = context.x, context.y if x < 0 or y < 0 or x >= map_settings.WIDTH or y >= map_settings.HEIGHT: raise dext_views.ViewError( code='outside_map', message='Запрашиваемая зона не принадлежит карте') map_info = map_info_storage.item terrain = map_info.terrain[y][x] cell = map_info.cells.get_cell(x, y) nearest_place_name = None nearest_place = map_info.get_dominant_place(x, y) if nearest_place: nearest_place_name = nearest_place.utg_name.form( utg_words.Properties(utg_relations.CASE.GENITIVE)) place = places_storage.places.get_by_coordinates(x, y) exchanges = [] terrain_points = [] building = places_storage.buildings.get_by_coordinates(x, y) return dext_views.Page( 'map/cell_info.html', content={ 'place': place, 'building': building, 'place_bills': places_info.place_info_bills(place) if place else None, 'place_chronicle': chronicle_prototypes.chronicle_info( place, conf.map_settings.CHRONICLE_RECORDS_NUMBER) if place else None, 'exchanges': exchanges, 'cell': cell, 'terrain': terrain, 'nearest_place_name': nearest_place_name, 'x': x, 'y': y, 'terrain_points': terrain_points, 'hero': heroes_logic.load_hero(account_id=context.account.id) if context.account.is_authenticated else None, 'resource': context.resource, 'ABILITY_TYPE': ABILITY_TYPE })
def preprocess(self, context): if context.tt_request.secret != self.secret: raise dext_views.ViewError( code='common.wrong_tt_secret', message='У Вас нет прав для проведения данной операции', http_status=dext_relations.HTTP_STATUS.INTERNAL_SERVER_ERROR)