def import_oice(request): oice = request.context if 'script' not in request.POST: raise ValidationError('ERR_IMPORT_SCRIPT_FILE_NOT_FOUND') user_email = request.authenticated_userid oice_id = request.matchdict['oice_id'] script = request.POST['script'] job_id = uuid.uuid4().hex language = fetch_oice_query_language(request, oice) try: text_wrapper = io.TextIOWrapper(script.file, encoding='utf-8-sig') script_text = text_wrapper.read() # handle Windows text file script_text = script_text.replace('\r', '') except Exception as error: raise ValidationError('ERR_IMPORT_SCRIPT_FILE_CANNOT_OPEN') worker = ImportOiceWorker(user_email, job_id, oice_id, script_text, language) worker.run() return { 'code': 200, 'jobId': job_id, }
def check_username_valid(request): username = request.json_body.get('username', None) if username: # check format of username if len(username) < 6: raise ValidationError('ERR_USERNAME_LENGTH_TOO_SHORT') elif not username[0].isalpha(): raise ValidationError('ERR_USERNAME_CAN_ONLY_START_WITH_LETTER') elif username.isdigit(): raise ValidationError('ERR_USERNAME_IS_A_NUMBER') invalid_char_regex = re.compile(r"[^a-zA-Z0-9\.\_]") if invalid_char_regex.search(username): raise ValidationError('ERR_USERNAME_CONTAINS_INVALID_CHARACTER') # check uniqueness of username user = UserQuery(DBSession) \ .fetch_user_by_username(username) \ .one_or_none() if user: raise ValidationError('ERR_USERNAME_NOT_UNIQUE') return { "code": 200, "message": "ok", }
def cancel_subscription(request): try: user = UserQuery(DBSession).fetch_user_by_email( email=request.authenticated_userid).one() subscription_list = stripe.Subscription.all(customer=user.customer_id, plan=get_stripe_plan_id(), status='active') if subscription_list and subscription_list.data: current_subscription = subscription_list.data[0] current_subscription.delete(at_period_end=True) user.is_cancelled = True log_dict = { 'action': 'cancelSubscribe', } log_dict = set_basic_info_membership_log(user, log_dict) log_dict = set_basic_info_log(request, log_dict) log_message(KAFKA_TOPIC_USER, log_dict) return {"user": user.serialize(), "message": "ok", "code": 200} else: raise ValidationError('subscription not found') except: e = sys.exc_info()[:2] raise ValidationError(str(e))
def add_attribute_definition(request): macro_id = request.json_body.get('macroId', None) asset_type = request.json_body.get('type', None) asset_type_id = request.json_body.get('assetTypeId', None) attribute_name = request.json_body.get('name', None) name = request.json_body.get('label', None) default_value = request.json_body.get('defaultValue', None) required = request.json_body.get('required', None) localizable = request.json_body.get('localizable', None) try: attribute_definition = AttributeDefinition( macro_id=macro_id, asset_type=asset_type, asset_type_id=asset_type_id, attribute_name=attribute_name, name=name, required=required, default_value=default_value, localizable=localizable) DBSession.add(attribute_definition) DBSession.flush() except ValueError as e: raise ValidationError(str(e)) except IntegrityError as e: raise ValidationError('Incorrect macro_id or asset_type_id.') else: return { 'code': 200, 'message': 'ok', 'attributeDefinition': attribute_definition.serialize() }
def handle_membership_update(user, product_id, original_transaction_id, expire_timestamp, developer_payload, platform, payout_amount): if developer_payload.split(':')[0] == 'subs': # handle developer_payload for Android subscription developer_payload = developer_payload.split(':')[2:] developer_payload = ':'.join(developer_payload) payload_dict = json.loads(developer_payload) if user is None: user = UserQuery(DBSession).fetch_user_by_email( payload_dict['email']).one() elif payload_dict['email'] != user.email: raise ValidationError('ERR_IAP_VALIDATOR_USER_NOT_MATCH') if 'oiceId' in payload_dict and user.is_new_subscribe \ and (UserSubscriptionPayoutQuery(DBSession).fetch_by_transaction_id(original_transaction_id) is None): oice_id = payload_dict['oiceId'] target_user = OiceQuery(DBSession).get_by_id(oice_id).story.users[0] user_subscription_payout = UserSubscriptionPayout(subscription_user_id=user.id, \ oice_id=oice_id, \ author_id=target_user.id, \ platform=platform, \ original_transaction_id=original_transaction_id, \ payout_amount=payout_amount) DBSession.add(user_subscription_payout) # handle share $ to oice author new_expire_date = datetime.utcfromtimestamp(expire_timestamp / 1000) if user.expire_date is None or new_expire_date > user.expire_date: if 'android' == platform: user_record = UserQuery( DBSession).fetch_user_by_android_transaction_id( original_transaction_id) if user_record is not None and user_record != user: raise ValidationError('ERR_IAP_RECEIPT_ALREADY_USED') else: user.android_product_id = product_id user.android_original_transaction_id = original_transaction_id elif 'ios' == platform: user_record = UserQuery( DBSession).fetch_user_by_ios_transaction_id( original_transaction_id) if user_record is not None and user_record != user: raise ValidationError('ERR_IAP_RECEIPT_ALREADY_USED') else: user.ios_product_id = product_id user.ios_original_transaction_id = original_transaction_id else: raise ValidationError("ERR_IAP_PLATFORM_UNKNOWN") user.role = 'paid' user.is_trial = False user.is_cancelled = False user.platform = platform user.expire_date = new_expire_date return user
def validate_tag(self, key, filename): if not filename: raise ValidationError("File name is needed.") if filename.startswith("_modmod"): raise ValidationError("This file name is reserved, " "please choose another name.") return filename
def ios_subscribe(request, validator_url): user = UserQuery(DBSession).fetch_user_by_email( email=request.authenticated_userid).one_or_none() if not user: raise HTTPForbidden if user.is_new_subscribe: log_action = 'startSubscribe' else: log_action = 'reSubscribe' payload = request.json_body receipt = {'receipt': payload['receipt']} r = requests.post(validator_url, data=receipt) result = None if r.status_code == requests.codes.ok: response_content = r.text response_dict = json.loads(response_content) code = response_dict['code'] if code != 0: raise ValidationError('ERR_IAP_VALIDATOR_NON_ZERO') product_id = response_dict['product_id'] original_transaction_id = response_dict['original_transaction_id'] expire_date = response_dict['expires_date'] developer_payload = payload['developerPayload'] payout_amount = int( math.ceil(get_iap_sub_price() * get_iap_sub_price_payout_ratio() * 100)) / 100.0 result = UserOperations.handle_membership_update( user, product_id, original_transaction_id, expire_date, developer_payload, "ios", payout_amount) else: raise ValidationError('ERR_IAP_VALIDATOR_CONN') length = math.ceil(len(payload["receipt"]) / 2) log_dict = { 'action': log_action, 'receiptPartA': payload["receipt"][0:length], 'receiptPartB': payload["receipt"][length:], } payload_dict = json.loads(developer_payload) if 'oiceId' in payload_dict: oice_id = payload_dict['oiceId'] oice = OiceQuery(DBSession).get_by_id(oice_id=oice_id) log_dict = set_basic_info_oice_log_author(oice=oice, log_dict=log_dict) log_dict = set_basic_info_membership_log(user, log_dict) log_dict = set_basic_info_log(request, log_dict) log_message(KAFKA_TOPIC_USER, log_dict) return {"user": user.serialize(), "message": result, "code": 200}
def update_library(request): library_id = request.matchdict['library_id'] try: library = LibraryQuery(DBSession)\ .get_library_by_id(library_id) # Hardcode config for now, does not work # if 'config' in request.json_body: # library.config_obj = request.json_body['config'] if 'meta' in request.POST: meta = json.loads(request.POST['meta']) if 'name' in meta: library.name = meta['name'] if 'description' in meta: library.description = meta['description'] if 'license' in meta: library.license = meta['license'] if 'price' in meta: if library.price <= 0: raise ValidationError('ERR_LIBRARY_PRICE_TIER_SHOULD_NOT_BE_ATTACHED') else: library.price = PriceTierQuery(DBSession).get_price_usd_by_tier(meta['price']) if 'launchedAt' in meta and 'isLaunched' in meta: if not meta['isLaunched'] and meta['launchedAt']: library.launched_at = None library.is_public = False elif meta['isLaunched'] and not meta['launchedAt']: library.launched_at = datetime.datetime.utcnow() library.is_public = True if 'coverStorage' in request.POST: cover_storage = request.POST['coverStorage'] factory = pyramid_safile.get_factory() extension = os.path.splitext(cover_storage.filename)[1] filename = 'cover_storage' + extension handle = factory.create_handle(filename, cover_storage.file) library.import_handle(handle) DBSession.add(library) return { 'code': 200, 'message': 'ok', 'library': library.serialize() } except ValueError as e: raise ValidationError(str(e))
def post_android_subscription(request): user = UserQuery(DBSession).fetch_user_by_email( email=request.authenticated_userid).one_or_none() if not user: raise HTTPForbidden if user.is_new_subscribe: log_action = 'startSubscribe' else: log_action = 'reSubscribe' payload = {'receipt': request.json_body['receipt']} url = get_android_iap_validator_url() r = requests.post(url, data=payload) result = None if r.status_code == requests.codes.ok: response_content = r.text response_dict = json.loads(response_content) code = response_dict['code'] if code != 0: raise ValidationError('ERR_IAP_VALIDATOR_NON_ZERO') product_id = response_dict['product_id'] original_transaction_id = response_dict['original_transaction_id'] expire_date = response_dict['expires_date'] developer_payload = response_dict['developer_payload'] payout_amount = int( math.ceil(get_iap_sub_price() * get_iap_sub_price_payout_ratio() * 100)) / 100.0 result = UserOperations.handle_membership_update( user, product_id, original_transaction_id, expire_date, developer_payload, "android", payout_amount) else: raise ValidationError('ERR_IAP_VALIDATOR_CONN') log_dict = { 'action': log_action, 'token': payload, } if developer_payload.split(':')[0] == 'subs': developer_payload = developer_payload.split(':')[2:] developer_payload = ':'.join(developer_payload) payload_dict = json.loads(developer_payload) if 'oiceId' in payload_dict: oice_id = payload_dict['oiceId'] oice = OiceQuery(DBSession).get_by_id(oice_id=oice_id) log_dict = set_basic_info_oice_log_author(oice=oice, log_dict=log_dict) log_dict = set_basic_info_membership_log(user, log_dict) log_dict = set_basic_info_log(request, log_dict) log_message(KAFKA_TOPIC_USER, log_dict) return {"user": user.serialize(), "message": result, "code": 200}
def create_character(request): library_id = request.matchdict['library_id'] try: name = request.json_body.get('name', None) description = request.json_body.get('description', None) width = request.json_body.get("width", 1080) height = request.json_body.get("height", 1080) is_generic = request.json_body.get("isGeneric", False) order = int(request.json_body.get("order", 0)) - 1 config = json.dumps(request.json_body.get("config", {}), sort_keys=True) except ValueError as e: raise ValidationError('Request object is invalid') try: # Try to insert a character character = Character( library_id=library_id, name=name, description=description, width=width, height=height, is_generic=is_generic, config=config, ) DBSession.add(character) DBSession.flush() if order and order != -1: parent_character = DBSession.query(Character) \ .filter(Character.order == order) \ .filter(Character.library_id == library_id) \ .first() operations.insert_character(DBSession, character, parent_character) else: order = CharacterQuery(DBSession) \ .get_last_order_in_library(library_id=library_id) character.order = order except exc.DBAPIError as e: raise ValidationError(str(e.orig)) else: return { 'code': 200, 'message': 'Success', 'character': character.serialize() }
def add_story(request): try: user = UserQuery(DBSession).fetch_user_by_email( email=request.authenticated_userid).one() story_name = 'My Story' if user.language[:2] == 'zh': story_name = '我的故事' elif user.language[:2] == 'ja': story_name = 'マイストーリー' story_name = '{} {}'.format(story_name, len(user.stories) + 1) story = Story(name=story_name, language=user.language) user.stories.append(story) DBSession.add(story) # flush because we need an ID DBSession.flush() return {"story": story.serialize(), "message": "ok", "code": 200} except ValueError as e: raise ValidationError(str(e))
def update_attribute_definition(request): object_id = request.matchdict['attribute_definition_id'] try: attribute_definition = DBSession.query(AttributeDefinition) \ .filter( AttributeDefinition.id == object_id ) \ .one() for key in [ 'type', 'assetTypeId', 'name', 'label', 'required', 'defaultValue', 'localizable' ]: if key in request.json_body: setattr(attribute_definition, key, request.json_body[key]) DBSession.add(attribute_definition) DBSession.flush() except ValueError as e: raise ValidationError(str(e)) else: return { 'code': 200, 'message': 'ok', 'attributeDefinition': attribute_definition.serialize() }
def check_is_language_valid(language): if language is None: return None if language.lower().replace( '-', '_') not in locale.locale_alias or len(language) > 5: raise ValidationError("ERR_INVALID_LANGUAGE") return language
def update_asset(request): asset = request.context try: meta = json.loads(request.POST['meta']) if 'credits' in meta: users = UserQuery(DBSession).fetch_user_by_ids(user_ids=meta['credits']) if users: asset.users = users else: asset.users = [] if 'creditsUrl' in meta: asset.credits_url = meta['creditsUrl'] if 'nameTw' in meta: asset.name_tw = meta['nameTw'] if 'nameEn' in meta: asset.name_en = meta['nameEn'] if 'nameJp' in meta: asset.name_jp = meta['nameJp'] job_id = None if 'asset' in request.POST: asset_file = request.POST['asset'] file_extension = os.path.splitext(asset_file.filename)[1].lower() # Set filename to <type><file extension> asset_file.filename = asset.asset_types[0].type_ + file_extension asset.filename = asset_file.filename if asset.asset_types[0].type_ == 'audio': job_id = uuid.uuid4().hex validate_audio_format(file_extension) handle_audio_asset_files(job_id, [asset], [asset_file]) else: factory = pyramid_safile.get_factory() handle = factory.create_handle(asset_file.filename, asset_file.file) if asset.asset_types[0].folder_name == 'bgimage': bgImageHandler = ResizeBackgroundImage(handle.dst) bgImageHandler.run() asset.import_handle(handle) DBSession.add(asset) response = { 'code': 200, 'message': 'ok', 'asset': asset.serialize(), } if job_id: response['jobId'] = job_id else: asset.library.updated_at = datetime.utcnow() return response except ValueError as e: raise ValidationError(str(e))
def connect_like_coin(request): session = DBSession() user = UserQuery(session).fetch_user_by_email(email=request.authenticated_userid).one() if 'likeCoinId' in request.json_body: like_coin_id = str(request.json_body.get('likeCoinId', '')) r = requests.get(get_likecoin_api_url() + '/users/id/' + like_coin_id) if r.status_code != requests.codes.ok: raise ValidationError('ERR_LIKECOIN_CONNECT_INVALID_ID') elif 'address' in request.json_body and 'signature' in request.json_body: address = str(request.json_body.get('address', '')) signature = request.json_body.get('signature') # Signature verification headers = { 'Content-type': 'application/json', 'Accept': 'text/plain', } verification_payload = { 'userId': user.id, 'address': address, 'signature': signature, } r = requests.post(get_cloud_function_api_base_url() + '/checkSignedLikeCoinAddress', data=json.dumps(verification_payload), headers=headers) if r.status_code != requests.codes.ok: raise ValidationError('ERR_LIKECOIN_ADDRESS_UNABLE_TO_VERIFY') r = requests.get(get_likecoin_api_url() + '/users/addr/' + address) if r.status_code != requests.codes.ok: raise ValidationError('ERR_LIKECOIN_CONNECT_INVALID_ADDRESS') like_coin_id = r.json().get('user') else: raise ValidationError('ERR_LIKECOIN_CONNECT_MISSING_PARAMS') if not user.like_coin_id: try: user.username = like_coin_id session.flush() except IntegrityError: raise ValidationError('ERR_LIKECOIN_CONNECT_USER_ID_DUPLICATED') try: user.like_coin_id = like_coin_id session.flush() except IntegrityError: raise ValidationError('ERR_LIKECOIN_CONNECT_DUPLICATED') elif user.like_coin_id != like_coin_id: raise ValidationError('ERR_LIKECOIN_CONNECT_ALREADY') return { 'code': 200, 'message': 'ok', 'user': user.serialize(), }
def get_itunesconnect_service_key(): # Look for the service key in the login controller js file # Possibly will break in the future url = ITUNESCONNECT_API_BASE_URL + '/itc/static-resources/controllers/login_cntrl.js' response = requests.get(url) matches = re.search(r"itcServiceKey = '(.*)'", response.text) if not matches: raise ValidationError('ERR_ITUNECONNECT_SERVICE_KEY_NOT_FOUND') return matches.group(1)
def post_translate(request): block = request.context source_language = check_is_language_valid( request.json_body.get("sourceLanguage", None)) target_language = check_is_language_valid( request.json_body.get("targetLanguage", None)) if not target_language: raise ValidationError("ERR_INVALID_TARGET_LANGUAGE") operations.translate_block(block, target_language, source_language) return {"message": "ok", "block": block.serialize(target_language)}
def update_user_mailchimp_stage(user=None, email=None, stage=1): if not user and email: user = UserQuery(DBSession).fetch_user_by_email(email).one_or_none() if not user: raise ValidationError('ERR_MAILCHIMP_UPDATE_WITHOUT_USER') if user.mailchimp_stage < stage: user.mailchimp_stage = stage update_mailchimp_field(email=email, stage=stage)
def add_product_tx(request): user = UserQuery(DBSession).fetch_user_by_email(email=request.authenticated_userid).one() try: product_type = request.matchdict['product_type'] product_id = request.json_body['productId'] amount = request.json_body['amount'] except KeyError: raise ValidationError('ERR_LIKECOIN_TX_PRODUCT_INFO_MISSING') tx = DBSession.query(LikecoinTx) \ .filter(LikecoinTx.user_id == user.id) \ .filter(LikecoinTx.product_type == product_type) \ .filter(LikecoinTx.product_id == product_id) \ .one_or_none() if tx is None: tx = LikecoinTx(user_id=user.id, product_type=product_type, product_id=product_id, amount=amount, max_reward=amount*get_likecoin_max_reward_ratio()) DBSession.add(tx) DBSession.flush() elif tx.status == 'failed': raise ValidationError('ERR_LIKECOIN_TX_PRODUCT_STATUS_FAILED') elif tx.tx_hash is not None: raise ValidationError('ERR_LIKECOIN_TX_PRODUCT_PURCHASED') return { 'id': tx.id, 'userId': user.id, 'productType': product_type, 'productId': product_id, 'from': tx.from_, 'to': tx.to, 'amount': amount, 'txHash': tx.tx_hash, 'status': tx.status, 'createdAt': tx.created_at.isoformat(), 'updatedAt': tx.updated_at.isoformat(), }
def add_asset(request): asset_type = request.matchdict['asset_type'] library_id = request.context.id user_email = request.authenticated_userid try: asset_types = DBSession.query(AssetType) \ .filter(AssetType.folder_name == asset_type) \ .all() meta = json.loads(request.POST['meta']) asset_file = request.POST['asset'] if 'asset' in request.POST \ else [request.POST['asset' + str(index)] for index in range(len(meta))] asset_category = asset_types[0].type_ if asset_category == 'audio': # only audio assets support multiple upload at this point return add_assets(asset_types, asset_type, meta, asset_file, library_id, user_email) else: order = 0 if 'order' in meta: order = int(meta['order']) - 1 parent_asset = DBSession.query(Asset) \ .filter(Asset.order == order) \ .filter(Asset.library_id == library_id) \ .first() if order else None operations.insert_asset(DBSession, asset, parent_asset) else: order = AssetQuery(DBSession) \ .get_last_order_in_library(library_id=library_id) asset = create_asset(asset_types, asset_type, meta, asset_file, library_id, user_email, order) DBSession.add(asset) DBSession.flush() if 'characterId' in meta: character_id = meta['characterId'] character = CharacterQuery(DBSession) \ .fetch_character_by_id(character_id=character_id).one() character.fgimages.append(asset) asset.library.updated_at = datetime.utcnow() asset.library.launched_at = datetime.utcnow() return { 'code': 200, 'message': 'ok', 'asset': asset.serialize(), } except ValueError as e: raise ValidationError(str(e))
def validate_likecoin_tx(request): user = UserQuery(DBSession).fetch_user_by_email(email=request.authenticated_userid).one() try: tx_hash = request.json_body['txhash'] except KeyError: raise ValidationError('ERR_LIKECOIN_TX_PRODUCT_INFO_MISSING') tx = request.context if tx.tx_hash != tx_hash: raise ValidationError('ERR_LIKECOIN_TX_VALIDATE_TX_HASH_NOT_MATCH') likecoin_tx = get_likecoin_tx_detail(tx.tx_hash) if likecoin_tx is None: raise ValidationError('ERR_LIKECOIN_TX_HASH_NOT_EXIST') if is_tx_amount_valid(tx.amount, likecoin_tx['value']) is not True: raise ValidationError('ERR_LIKECOIN_TX_VALIDATE_AMOUNT_NOT_MATCH') if tx.from_ != likecoin_tx['from']: raise ValidationError('ERR_LIKECOIN_TX_VALIDATE_FROM_ADDRESS_NOT_MATCH') if not (tx.to == likecoin_tx['to'] == get_oice_likecoin_wallet()): raise ValidationError('ERR_LIKECOIN_TX_VALIDATE_TO_ADDRESS_NOT_MATCH') product = None if tx.product_type == 'library': library = LibraryQuery(DBSession).get_library_by_id(tx.product_id) return { 'product': library.serialize_min(), } return {}
def visit_option_block(self, block, language): attrs = block.get_localized_attributes(language) question = attrs.get('question', '') script = '@optionstart\n' + ScriptVisitor.print_dialog_text( question) + '\n' if 'answers' in attrs: try: answers = json.loads(attrs['answers']) except ValueError: raise ValidationError( str(block.id) + 'ERR_OPTION_BLOCK_ANSWERS_NOT_IN_JSON_FORMAT') else: for answer_index, answer in enumerate(answers): script += '@optionanswer storage="%s" target="%s" text="%s" oiceid=%d blockid=%d index=%d\n' % ( language + '.ks', answer['target'], quote(answer['content']).replace('%', '!'), # Encode text block.oice_id, block.id, answer_index, ) else: raise ValidationError('ERR_OPTION_BLOCK_ANSWERS_NOT_FOUND') script += self._post_oice_action({ 'type': 'oice.didShowOptions', 'payload': { 'oiceId': block.oice_id, 'blockId': block.id, 'question': question, 'answers': answers, }, }) script += '@optionend\n' return script
def post_translate(request): oice = request.context source_language = check_is_language_valid(request.json_body.get("sourceLanguage", None)) target_language = check_is_language_valid(request.json_body.get("targetLanguage", None)) if not target_language: raise ValidationError("ERR_INVALID_TARGET_LANGUAGE") translate_oice(oice, target_language, source_language) return { "code": 200, "message": "ok", "oice": oice.serialize(language=target_language), }
def get_og(request): oice_uuid = request.matchdict['oice_uuid'] oice = OiceQuery(DBSession).get_by_uuid(uuid=oice_uuid) if not oice: raise ValidationError('ERR_OICE_NOT_FOUND') user = UserQuery(DBSession).fetch_user_by_email(email=request.authenticated_userid).one_or_none() return { 'oice': oice.serialize(user, language=fetch_oice_query_language(request, oice)), 'code': 200, 'message': 'ok' }
def remove_selected_library_from_user(request): user = UserQuery(DBSession).fetch_user_by_email(email=request.authenticated_userid).one() library_to_be_removed = request.context if library_to_be_removed.has_user_purchased(user): user.libraries_selected.remove(library_to_be_removed) else: raise ValidationError('ERR_REMOVE_NOT_PURCHASED_LIBRARY_FROM_LIBRARIES_SELECTED') return { 'code': 200, 'message': 'ok', }
def add_selected_library_to_user(request): user = UserQuery(DBSession).fetch_user_by_email(email=request.authenticated_userid).one() library_to_be_added = request.context if library_to_be_added.has_user_purchased(user): user.libraries_selected.append(library_to_be_added) else: raise ValidationError('ERR_ADD_NOT_PURCHASED_LIBRARY_TO_LIBRARIES_SELECTED') return { 'code': 200, 'message': 'ok', }
def redeem_voucher(request): user = UserQuery(DBSession).fetch_user_by_email( email=request.authenticated_userid).one() voucher_code = request.matchdict.get('code') url = get_voucher_api_url() + '/voucher/' + voucher_code + '/redeem' try: r = requests.post( url=url, headers={'Authentication': get_voucher_api_key()}, data={'userId': user.id}, ) response = r.json() except Exception: pass else: code = response.get('code') if code == 'SUCCESS': new_expiry_date = datetime.strptime( response['redemption']['expireAt'], '%Y-%m-%dT%H:%M:%SZ') # Allow extend the expiry date if user.expire_date is not None and new_expiry_date - datetime.now( ) > new_expiry_date - user.expire_date: new_expiry_date = user.expire_date + (new_expiry_date - datetime.now()) if user.expire_date is None or new_expiry_date > user.expire_date: user.role = 'paid' user.is_trial = False user.is_cancelled = False user.expire_date = new_expiry_date return { 'code': 200, 'message': 'ok', 'user': user.serialize(), 'newExpiryDate': new_expiry_date.isoformat(), } elif code == 'INVALID_CODE': raise ValidationError('ERR_VOUCHER_CODE_INVALID') elif code == 'NOT_YET': raise ValidationError('ERR_VOUCHER_NOT_YET_EFFECTIVE') elif code == 'EXPIRED': raise ValidationError('ERR_VOUCHER_EXPIRED') elif code == 'REDEEMED_ALREADY': raise ValidationError('ERR_VOUCHER_REDEEMED_ALREADY') elif code == 'REACH_LIMIT': raise ValidationError('ERR_VOUCHER_REDEMPTION_LIMIT_REACH') raise ValidationError('ERR_VOUCHER_SERVICE_FAILURE')
def read_npcdata(npcdata_path): if not os.path.exists(npcdata_path): return [] with open(npcdata_path, 'r') as fp: content = fp.read() script_content = re.findall('\[o2_iscript\]([\s\S]*)\[o2_endscript\]', content) if (len(script_content) == 0): raise ValidationError("invalid npcdata.ks format") return script_content
def get_stripe_connect_webhook(request): try: user = None event_json = request.json_body event = stripe.Event.retrieve(event_json["id"]) if 'account.application.deauthorized' == event.type: account = event.data.object user = UserQuery(DBSession).fetch_user_by_stripe_account_id( stripe_account_id=account.id) user.stripe_account_id = None return {"message": "ok", "code": 200} except: e = sys.exc_info()[:2] raise ValidationError(str(e))
def get_translate(request): story = request.context source_language = story.language target_language = fetch_story_query_language(request, story) if not target_language: raise ValidationError("ERR_INVALID_TARGET_LANGUAGE") result = translate_story_preview(story, target_language, source_language) return { 'code': 200, 'message': 'ok', 'result': result, }