예제 #1
0
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,
    }
예제 #2
0
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",
    }
예제 #3
0
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()
        }
예제 #5
0
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
예제 #6
0
    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
예제 #7
0
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}
예제 #8
0
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))
예제 #9
0
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}
예제 #10
0
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()
        }
예제 #11
0
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))
예제 #12
0
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()
        }
예제 #13
0
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
예제 #14
0
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))
예제 #15
0
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(),
    }
예제 #16
0
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)
예제 #17
0
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)}
예제 #18
0
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)
예제 #19
0
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(),
    }
예제 #20
0
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))
예제 #21
0
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 {}
예제 #22
0
    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
예제 #23
0
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),
    }
예제 #24
0
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'
    }
예제 #25
0
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',
    }
예제 #26
0
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',
    }
예제 #27
0
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')
예제 #28
0
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
예제 #29
0
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))
예제 #30
0
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,
    }