Esempio n. 1
0
def put(args):
    targetFile = args[0]
    targetFileName = os.path.basename(targetFile)
    patchedFileName = targetFileName.split(
        ".")[0] + "_patched." + targetFileName.split(".")[1]

    with open(targetFile, "rb") as hostFile, open(patchedFileName,
                                                  "wb+") as patchedFile:
        patchedFile.write(hostFile.read())
        index = 1
        while index < len(args):
            sourceFile = args[index]
            sourceFileName = os.path.basename(sourceFile)
            print("trying to hide", sourceFile, "...")
            with open(sourceFile, "rb") as fileToHide:
                patchedFile.write(
                    binascii.hexlify(
                        bytes(sourceFileName + DELIMITER, ENCODING)))
                patchedFile.write(binascii.hexlify(fileToHide.read()))
                patchedFile.write(
                    binascii.hexlify(
                        bytes(sourceFileName + DELIMITER, ENCODING)))
                print("...", sourceFileName, "hidden!")
            index += 1

    util = TimeUtil()
    util.setModTime(patchedFileName, util.getModTime(targetFile))
    def __create_like_notification(self, article_info):
        notification_table = self.dynamodb.Table(os.environ['NOTIFICATION_TABLE_NAME'])
        notification_id = '-'.join([settings.LIKE_NOTIFICATION_TYPE, article_info['user_id'], article_info['article_id']])
        notification = notification_table.get_item(Key={'notification_id': notification_id}).get('Item')

        liked_count = self.__get_article_likes_count()

        if notification:
            notification_table.update_item(
                Key={
                    'notification_id': notification_id
                },
                UpdateExpression="set sort_key = :sort_key, article_title = :article_title, liked_count = :liked_count",
                ExpressionAttributeValues={
                    ':sort_key': TimeUtil.generate_sort_key(),
                    ':article_title': article_info['title'],
                    ':liked_count': liked_count
                }
            )
        else:
            notification_table.put_item(Item={
                    'notification_id': notification_id,
                    'user_id': article_info['user_id'],
                    'article_id': article_info['article_id'],
                    'article_title': article_info['title'],
                    'sort_key': TimeUtil.generate_sort_key(),
                    'type': settings.LIKE_NOTIFICATION_TYPE,
                    'liked_count': liked_count,
                    'created_at': int(time.time())
                }
            )
Esempio n. 3
0
def main():
    print('-----------------------', datetime.datetime.now())
    sw = {
        'w': lambda: TimeUtil.get_time_weeks(FLAGS.time_interval),
        'd': lambda: TimeUtil.get_time_days(FLAGS.time_interval),
        'h': lambda: TimeUtil.get_time_hours(FLAGS.time_interval),
        'm': lambda: TimeUtil.get_time_minutes(FLAGS.time_interval, TIME_END),
        's': lambda: TimeUtil.get_time_seconds(FLAGS.time_interval),
    }
    if FLAGS.time_interval > 0:
        global TIME_BEGIN
        global TIME_END
        TIME_BEGIN, TIME_END = sw[FLAGS.time_format]()
    print(TIME_BEGIN, TIME_BEGIN - FLAGS.time_period * 1000)

    hadoop_util.get_cluster_information()
    hadoop_util.get_commonjobs_information()
    response = requests.get("http://127.0.0.1:5001/update/all")
    if response.status_code == 200:
        print("success request http://127.0.0.1:5001/update/all")
        # response = requests.get('http://127.0.0.1:5002/train_lstm')
        # if response.status_code == 200:
        #   print("success request http://127.0.0.1:5002/train_lstm")
        # else:
        #   print("fail request http://127.0.0.1:5002/train_lstm")
    else:
        print("fail request http://127.0.0.1:5001/update/all")
Esempio n. 4
0
 def test_datetime(self):
     timezone_offset = self.request.get('tz_offset')
     date = self.request.get('datetime')
     to_timezone_offset = self.request.get('to_tz_offset')
     if not timezone_offset or not date or not to_timezone_offset:
         return False
     date = TimeUtil.str_to_utc_datetime(int(timezone_offset), date)
     result = TimeUtil.utc_datetime_to_str(int(to_timezone_offset), date)
     self.response.out.write(result)
Esempio n. 5
0
def main():
    query_parameters = {"state": FLAGS.state}
    sw = {
        'w': lambda: TimeUtil.get_time_weeks(FLAGS.time_interval),
        'd': lambda: TimeUtil.get_time_days(FLAGS.time_interval),
        'h': lambda: TimeUtil.get_time_hours(FLAGS.time_interval),
        'm': lambda: TimeUtil.get_time_minutes(FLAGS.time_interval),
        's': lambda: TimeUtil.get_time_seconds(FLAGS.time_interval),
    }
    if FLAGS.time_interval > 0:
        finished_time_begin, finished_time_end = sw[FLAGS.time_format]()
        query_parameters["finishedTimeBegin"] = finished_time_begin
        query_parameters["finishedTimeEnd"] = finished_time_end

    thread_main(query_parameters)
    def __create_tip_info(self, transaction_hash, tip_value, burn_transaction,
                          article_info):
        tip_table = self.dynamodb.Table(os.environ['TIP_TABLE_NAME'])

        sort_key = TimeUtil.generate_sort_key()
        user_id = self.event['requestContext']['authorizer']['claims'][
            'cognito:username']

        epoch = int(time.time())

        tip_info = {
            'user_id': user_id,
            'to_user_id': article_info['user_id'],
            'tip_value': tip_value,
            'article_id': self.params['article_id'],
            'article_title': article_info['title'],
            'transaction': transaction_hash,
            'burn_transaction': burn_transaction,
            'uncompleted': 1,
            'sort_key': sort_key,
            'target_date': time.strftime('%Y-%m-%d', time.gmtime(epoch)),
            'created_at': epoch
        }

        tip_table.put_item(Item=tip_info,
                           ConditionExpression='attribute_not_exists(user_id)')
    def __notify_purchaser(self, article_info, user_id, transaction_status):
        notification_table = self.dynamodb.Table(
            os.environ['NOTIFICATION_TABLE_NAME'])

        notification_table.put_item(
            Item={
                'notification_id':
                self.__get_randomhash(),
                'user_id':
                user_id,
                'acted_user_id':
                user_id,
                'article_id':
                article_info['article_id'],
                'article_user_id':
                article_info['user_id'],
                'article_title':
                article_info['title'],
                'sort_key':
                TimeUtil.generate_sort_key(),
                'type':
                settings.ARTICLE_PURCHASE_TYPE if transaction_status ==
                'done' else settings.ARTICLE_PURCHASE_ERROR_TYPE,
                'price':
                int(article_info['price']),
                'created_at':
                int(time.time())
            })
    def exec_main_proc(self):
        sort_key = TimeUtil.generate_sort_key()
        article_id = self.__generate_article_id(sort_key)
        params = json.loads(self.event.get('body'))

        try:
            self.__create_article_info(params, sort_key, article_id)

            try:
                self.__create_article_content(params, article_id)
            except Exception as err:
                logging.fatal(err)
                traceback.print_exc()
            finally:
                return {
                    'statusCode': 200,
                    'body': json.dumps({'article_id': article_id})
                }
        except ClientError as e:
            if e.response['Error'][
                    'Code'] == 'ConditionalCheckFailedException':
                return {
                    'statusCode': 400,
                    'body': json.dumps({'message': 'Already exists'})
                }
            else:
                raise
Esempio n. 9
0
 def test_changetime(self):
     time_input = [1509522118051, 1509522060561, 1509518440216]
     time_result = [
         "2017-11-01 15:41:58", "2017-11-01 15:41:00", "2017-11-01 14:40:40"
     ]
     for input, pre_result in zip(time_input, time_result):
         result = TimeUtil.change_to_time(input)
         self.assertAlmostEqual(pre_result, str(result))
Esempio n. 10
0
def main():
    print('-----------------------', datetime.datetime.now())
    sw = {
        'w': lambda: TimeUtil.get_time_weeks(FLAGS.time_interval),
        'd': lambda: TimeUtil.get_time_days(FLAGS.time_interval),
        'h': lambda: TimeUtil.get_time_hours(FLAGS.time_interval),
        'm': lambda: TimeUtil.get_time_minutes(FLAGS.time_interval, TIME_END),
        's': lambda: TimeUtil.get_time_seconds(FLAGS.time_interval),
    }
    if FLAGS.time_interval > 0:
        global TIME_BEGIN
        global TIME_END
        TIME_BEGIN, TIME_END = sw[FLAGS.time_format]()
    print(TIME_BEGIN, TIME_BEGIN - FLAGS.time_period * 1000)

    hadoop_util.get_cluster_information()
    hadoop_util.get_commonjobs_information()
Esempio n. 11
0
 def to_object(self, tz_offset):
     return {
         'key': self.key.urlsafe(),
         'goal': self.goal,
         'start_date': TimeUtil.utc_datetime_to_str(tz_offset,
                                                    self.start_date),
         'fulfill_status': self.fulfill_status
     }
Esempio n. 12
0
 def handle_add_diary(self):
     diary = self.request.get('diary')
     tz_offset = self.request.get('tz_offset')
     date = self.request.get('date')
     if not self.email or not diary or not tz_offset or not date:
         return False
     date = TimeUtil.str_to_utc_datetime(int(tz_offset), date)
     diary = Diary.create(self.email, date, diary)
     return True, {'key': diary.key.urlsafe()}
Esempio n. 13
0
 def handle_update_diary(self):
     key = self.request.get('key')
     diary = self.request.get('diary')
     tz_offset = self.request.get('tz_offset')
     date = self.request.get('date')
     if not self.email or not key or not diary or not tz_offset or not date:
         return False
     date = TimeUtil.str_to_utc_datetime(int(tz_offset), date)
     return Diary.update(key, self.email, date, diary)
Esempio n. 14
0
 def handle_add_goal(self):
     goal = self.request.get('goal')
     timezone_offset = self.request.get('tz_offset')
     start_date = self.request.get('start_date')
     if not self.email or not goal or not timezone_offset or not start_date:
         return False
     start_date = TimeUtil.str_to_utc_datetime(int(timezone_offset),
                                               start_date)
     goal = TwoWeekGoal.create(self.email, goal, start_date)
     return True, {'key': goal.key.urlsafe()}
Esempio n. 15
0
 def handle_passcode_add_diary(self):
     """ Used to migrate from DailyNote2. """
     diary = self.request.get('diary')
     tz_offset = self.request.get('tz_offset')
     date = self.request.get('date')
     email = self.request.get('email')
     if not email or diary is None or not tz_offset or not date:
         return False
     date = TimeUtil.str_to_utc_datetime(int(tz_offset), date)
     diary = Diary.create(email, date, diary)
     return True, {'key': diary.key.urlsafe()}
Esempio n. 16
0
 def handle_get_diaries(self):
     tz_offset = self.request.get('tz_offset')
     count_limit = self.request.get('count_limit')
     cursor = self.request.get('cursor')
     min_date = self.request.get('min_date')
     max_date = self.request.get('max_date')
     if not self.email or not tz_offset or not count_limit:
         return False
     count_limit = int(count_limit)
     tz_offset = int(tz_offset)
     if min_date:
         min_date = TimeUtil.str_to_utc_datetime(tz_offset, min_date)
     if max_date:
         max_date = TimeUtil.str_to_utc_datetime(tz_offset, max_date)
     diaries, next_cursor = Diary.query_instances(self.email, count_limit, cursor, min_date,
         max_date)
     data = []
     for diary in diaries:
         data.append(diary.to_object(tz_offset))
     result = {'data': data}
     if next_cursor:
         result['next_cursor'] = next_cursor
     return True, result
 def __create_article_liked_user(self, article_liked_user_table):
     epoch = int(time.time())
     article_liked_user = {
         'article_id': self.event['pathParameters']['article_id'],
         'user_id': self.event['requestContext']['authorizer']['claims']['cognito:username'],
         'article_user_id': self.__get_article_user_id(self.event['pathParameters']['article_id']),
         'created_at': epoch,
         'target_date': time.strftime('%Y-%m-%d', time.gmtime(epoch)),
         'sort_key': TimeUtil.generate_sort_key()
     }
     article_liked_user_table.put_item(
         Item=article_liked_user,
         ConditionExpression='attribute_not_exists(article_id)'
     )
    def __create_article_history_and_update_sort_key(self):
        # update sort_key
        article_history_table = self.dynamodb.Table(
            os.environ['ARTICLE_HISTORY_TABLE_NAME'])
        article_histories = article_history_table.query(
            KeyConditionExpression=Key('article_id').eq(
                self.params['article_id']))['Items']

        if len(article_histories) == 0:
            sort_key = TimeUtil.generate_sort_key()
            article_info_table = self.dynamodb.Table(
                os.environ['ARTICLE_INFO_TABLE_NAME'])
            article_info_table.update_item(
                Key={
                    'article_id': self.params['article_id'],
                },
                UpdateExpression=
                'set sort_key = :sort_key, published_at = :published_at',
                ExpressionAttributeValues={
                    ':sort_key': sort_key,
                    ':published_at': int(time.time())
                })

        # create article_history
        article_content_table = self.dynamodb.Table(
            os.environ['ARTICLE_CONTENT_TABLE_NAME'])
        article_content = article_content_table.get_item(
            Key={
                'article_id': self.params['article_id']
            }).get('Item')

        Item = {
            'article_id': article_content['article_id'],
            'title': article_content['title'],
            'body': article_content['body'],
            'created_at': int(time.time())
        }

        # 金額や有料記事本文が含まれている場合一緒に更新する
        if self.params.get('price') is not None and self.params.get(
                'paid_body') is not None:
            Item.update({
                'price': self.params.get('price'),
                'paid_body': self.params.get('paid_body')
            })

        article_history_table.put_item(Item=Item)
Esempio n. 19
0
 def handle_update_goal(self):
     key = self.request.get('key')
     goal = self.request.get('goal')
     timezone_offset = self.request.get('tz_offset')
     start_date = self.request.get('start_date')
     fulfill_status = self.request.get('fulfill_status')
     if not key or not self.email:
         return False
     if start_date:
         if not timezone_offset:
             return False
         start_date = TimeUtil.str_to_utc_datetime(int(timezone_offset),
                                                   start_date)
     if fulfill_status:
         fulfill_status = int(fulfill_status)
     return TwoWeekGoal.update(self.email, key, goal, start_date,
                               fulfill_status)
Esempio n. 20
0
    def __create_comment_notification(self, article_info, comment_id, user_id):
        notification_table = self.dynamodb.Table(
            os.environ['NOTIFICATION_TABLE_NAME'])
        notification_id = '-'.join([
            settings.COMMENT_NOTIFICATION_TYPE, article_info['user_id'],
            comment_id
        ])

        notification_table.put_item(
            Item={
                'notification_id': notification_id,
                'user_id': article_info['user_id'],
                'article_id': article_info['article_id'],
                'article_title': article_info['title'],
                'acted_user_id': user_id,
                'sort_key': TimeUtil.generate_sort_key(),
                'type': settings.COMMENT_NOTIFICATION_TYPE,
                'created_at': int(time.time())
            })
    def __notification(self, user_id, announce_url):
        notification_table = self.dynamodb.Table(
            os.environ['NOTIFICATION_TABLE_NAME'])

        notification_id = self.__get_randomhash()

        notification_table.put_item(
            Item={
                'notification_id': notification_id,
                'user_id': user_id,
                'sort_key': TimeUtil.generate_sort_key(),
                'type': settings.CSVDOWNLOAD_NOTIFICATION_TYPE,
                'created_at': int(time.time()),
                'announce_body':
                '全トークン履歴のcsvのダウンロード準備が完了しました。本通知をクリックしてダウンロードしてください。',
                'announce_url': announce_url
            })

        self.__update_unread_notification_manager(user_id)
Esempio n. 22
0
    def exec_main_proc(self):
        sort_key = TimeUtil.generate_sort_key()
        user_id = self.event['requestContext']['authorizer']['claims'][
            'cognito:username']

        comment_id = self.__generate_comment_id(sort_key)

        comment_table = self.dynamodb.Table(os.environ['COMMENT_TABLE_NAME'])

        comment = {
            'comment_id': comment_id,
            'article_id': self.params['article_id'],
            'text': TextSanitizer.sanitize_text(self.params['text']),
            'user_id': user_id,
            'sort_key': sort_key,
            'created_at': int(time.time())
        }

        comment_table.put_item(
            Item=comment,
            ConditionExpression='attribute_not_exists(comment_id)')

        # 優先度が低いため通知処理は失敗しても握り潰して200を返す(ログは出して検知できるようにする)
        try:
            article_info_table = self.dynamodb.Table(
                os.environ['ARTICLE_INFO_TABLE_NAME'])
            article_info = article_info_table.get_item(
                Key={'article_id': self.params['article_id']})['Item']

            if self.__is_notifiable_comment(article_info, user_id):
                self.__create_comment_notification(article_info, comment_id,
                                                   user_id)
                self.__update_unread_notification_manager(article_info)

        except Exception as err:
            logging.fatal(err)
            traceback.print_exc()
        finally:
            return {
                'statusCode': 200,
                'body': json.dumps({'comment_id': comment_id})
            }
Esempio n. 23
0
    def notify_article_comment(dynamodb, article_info, comment, target_user_id,
                               comment_type):
        if comment_type not in settings.COMMENT_NOTIFICATION_TYPES:
            raise ValueError('Invalid comment type ' + comment_type)

        notification_table = dynamodb.Table(
            os.environ['NOTIFICATION_TABLE_NAME'])

        notification_id = '-'.join(
            [comment_type, target_user_id, comment['comment_id']])

        notification_table.put_item(
            Item={
                'notification_id': notification_id,
                'user_id': target_user_id,
                'article_id': article_info['article_id'],
                'article_user_id': article_info['user_id'],
                'article_title': article_info['title'],
                'acted_user_id': comment['user_id'],
                'sort_key': TimeUtil.generate_sort_key(),
                'type': comment_type,
                'created_at': int(time.time())
            })
    def exec_main_proc(self):
        ################
        # get parameter
        ################
        # get article info
        article_info_table = self.dynamodb.Table(
            os.environ['ARTICLE_INFO_TABLE_NAME'])
        article_info = article_info_table.get_item(
            Key={
                'article_id': self.params['article_id']
            }).get('Item')
        # purchase article
        paid_articles_table = self.dynamodb.Table(
            os.environ['PAID_ARTICLES_TABLE_NAME'])
        paid_status_table = self.dynamodb.Table(
            os.environ['PAID_STATUS_TABLE_NAME'])
        # eth_address
        article_user_eth_address = UserUtil.get_private_eth_address(
            self.cognito, article_info['user_id'])
        user_eth_address = self.event['requestContext']['authorizer'][
            'claims']['custom:private_eth_address']
        # transaction_count
        transaction_count = PrivateChainUtil.get_transaction_count(
            user_eth_address)

        ################
        # validation
        ################
        # does not purchase same user's article
        user_id = self.event['requestContext']['authorizer']['claims'][
            'cognito:username']
        if article_info['user_id'] == user_id:
            raise ValidationError('Can not purchase own article')
        # validate raw_transaction
        # purchase
        purchase_data = PrivateChainUtil.get_data_from_raw_transaction(
            self.params['purchase_signed_transaction'], transaction_count)
        PrivateChainUtil.validate_erc20_transfer_data(
            purchase_data, article_user_eth_address)
        # burn
        transaction_count = PrivateChainUtil.increment_transaction_count(
            transaction_count)
        burn_data = PrivateChainUtil.get_data_from_raw_transaction(
            self.params['burn_signed_transaction'], transaction_count)
        PrivateChainUtil.validate_erc20_transfer_data(
            burn_data, '0x' + os.environ['BURN_ADDRESS'])

        # burn 量が正しいこと
        purchase_value = int(purchase_data[72:], 16)
        burn_value = int(burn_data[72:], 16)
        calc_burn_value = int(Decimal(purchase_value) / Decimal(9))
        if burn_value != calc_burn_value:
            raise ValidationError('burn_value is invalid.')

        # purchase_value が記事で指定されている金額に基づいた量が設定されていること
        DBUtil.validate_latest_price(self.dynamodb, self.params['article_id'],
                                     purchase_value)

        ################
        # purchase
        ################
        sort_key = TimeUtil.generate_sort_key()
        # 多重リクエストによる不必要なレコード生成を防ぐためにpaid_statusレコードを生成
        self.__create_paid_status(paid_status_table, user_id)
        # 購入のトランザクション処理
        purchase_transaction = PrivateChainUtil.send_raw_transaction(
            self.params['purchase_signed_transaction'])
        # 購入記事データを作成
        self.__create_paid_article(paid_articles_table, article_info,
                                   purchase_transaction, sort_key)
        # プライベートチェーンへのポーリングを行いトランザクションの承認状態を取得
        transaction_status = self.__polling_to_private_chain(
            purchase_transaction)
        # トランザクションの承認状態をpaid_articleとpaid_statusに格納
        self.__update_transaction_status(article_info, paid_articles_table,
                                         transaction_status, sort_key,
                                         paid_status_table, user_id)

        # 購入のトランザクションが成功した時のみバーンのトランザクションを発行する
        if transaction_status == 'done':
            try:
                # 購入に成功した場合、著者の未読通知フラグをTrueにする
                self.__update_unread_notification_manager(
                    article_info['user_id'])
                # 著者へ通知を作成
                self.__notify_author(article_info, user_id)
                # バーンのトランザクション処理
                burn_transaction = PrivateChainUtil.send_raw_transaction(
                    self.params['burn_signed_transaction'])
                # バーンのトランザクションを購入テーブルに格納
                self.__add_burn_transaction_to_paid_article(
                    burn_transaction, paid_articles_table, article_info,
                    sort_key)
            except Exception as err:
                logging.fatal(err)
                traceback.print_exc()
        # 記事購入者へは購入処理中の場合以外で通知を作成
        if transaction_status == 'done' or transaction_status == 'fail':
            self.__update_unread_notification_manager(user_id)
            self.__notify_purchaser(article_info, user_id, transaction_status)

        return {
            'statusCode': 200,
            'body': json.dumps({'status': transaction_status})
        }
    def exec_main_proc(self):
        # get article info
        article_info_table = self.dynamodb.Table(
            os.environ['ARTICLE_INFO_TABLE_NAME'])
        article_info = article_info_table.get_item(
            Key={
                'article_id': self.params['article_id']
            }).get('Item')
        # does not purchase same user's article
        user_id = self.event['requestContext']['authorizer']['claims'][
            'cognito:username']
        if article_info['user_id'] == user_id:
            raise ValidationError('Can not purchase own article')

        # purchase article
        paid_articles_table = self.dynamodb.Table(
            os.environ['PAID_ARTICLES_TABLE_NAME'])
        paid_status_table = self.dynamodb.Table(
            os.environ['PAID_STATUS_TABLE_NAME'])
        article_user_eth_address = self.__get_user_private_eth_address(
            article_info['user_id'])
        user_eth_address = self.event['requestContext']['authorizer'][
            'claims']['custom:private_eth_address']
        price = self.params['price']

        auth = AWSRequestsAuth(
            aws_access_key=os.environ['PRIVATE_CHAIN_AWS_ACCESS_KEY'],
            aws_secret_access_key=os.
            environ['PRIVATE_CHAIN_AWS_SECRET_ACCESS_KEY'],
            aws_host=os.environ['PRIVATE_CHAIN_EXECUTE_API_HOST'],
            aws_region='ap-northeast-1',
            aws_service='execute-api')
        headers = {'content-type': 'application/json'}

        sort_key = TimeUtil.generate_sort_key()

        # 多重リクエストによる不必要なレコード生成を防ぐためにpaid_statusレコードを生成
        self.__create_paid_status(paid_status_table, user_id)
        # 購入のトランザクション処理
        purchase_transaction = self.__create_purchase_transaction(
            auth, headers, user_eth_address, article_user_eth_address, price)
        # 購入記事データを作成
        self.__create_paid_article(paid_articles_table, article_info,
                                   purchase_transaction, sort_key)
        # プライベートチェーンへのポーリングを行いトランザクションの承認状態を取得
        transaction_status = self.__polling_to_private_chain(
            purchase_transaction, auth, headers)
        # トランザクションの承認状態をpaid_artilcleとpaid_statusに格納
        self.__update_transaction_status(article_info, paid_articles_table,
                                         transaction_status, sort_key,
                                         paid_status_table, user_id)

        # 購入のトランザクションが成功した時のみバーンのトランザクションを発行する
        if transaction_status == 'done':
            try:
                # 購入に成功した場合、著者の未読通知フラグをTrueにする
                self.__update_unread_notification_manager(
                    article_info['user_id'])
                # 著者へ通知を作成
                self.__notify_author(article_info, user_id)
                # バーンのトランザクション処理
                burn_transaction = self.__burn_transaction(
                    price, user_eth_address, auth, headers)
                # バーンのトランザクションを購入テーブルに格納
                self.__add_burn_transaction_to_paid_article(
                    burn_transaction, paid_articles_table, article_info,
                    sort_key)
            except Exception as err:
                logging.fatal(err)
                traceback.print_exc()
        # 記事購入者へは購入処理中の場合以外で通知を作成
        if transaction_status == 'done' or transaction_status == 'fail':
            self.__update_unread_notification_manager(user_id)
            self.__notify_purchaser(article_info, user_id, transaction_status)

        return {
            'statusCode': 200,
            'body': json.dumps({'status': transaction_status})
        }
Esempio n. 26
0
    def test_generate_sort_key(self):
        sort_key = TimeUtil.generate_sort_key()

        self.assertEqual(len(str(sort_key)), 16)
        self.assertTrue(type(sort_key) is int)
Esempio n. 27
0
 def to_object(self, tz_offset):
     return {
         'key': self.key.urlsafe(),
         'date': TimeUtil.utc_datetime_to_str(tz_offset, self.date),
         'diary': self.diary
     }
    def exec_main_proc(self):
        from_user_eth_address = self.event['requestContext']['authorizer'][
            'claims']['custom:private_eth_address']
        recipient_eth_address = self.params['recipient_eth_address']
        send_value = self.params['send_value']
        sort_key = TimeUtil.generate_sort_key()
        user_id = self.event['requestContext']['authorizer']['claims'][
            'cognito:username']

        # 日次の限度額を超えていた場合は例外
        sum_price = self.__get_token_send_value_today(user_id)
        if Decimal(os.environ['DAILY_LIMIT_TOKEN_SEND_VALUE']
                   ) < sum_price + Decimal(send_value):
            raise ValidationError('Token withdrawal limit has been exceeded.')

        # allowance を取得
        allowance = self.__get_allowance(from_user_eth_address)
        # transaction_count を取得
        transaction_count = self.__get_transaction_count(from_user_eth_address)
        # 既に approve されている場合(allowance の戻り値が "0x0" ではない場合)、該当の approve を削除する(0 で更新)
        if allowance != '0x0':
            self.__approve(from_user_eth_address, 0, transaction_count)
            transaction_count = self.__increment_transaction_count(
                transaction_count)

        # approve 実施
        approve_transaction_hash = self.__approve(from_user_eth_address,
                                                  send_value,
                                                  transaction_count)
        transaction_count = self.__increment_transaction_count(
            transaction_count)
        self.__create_send_info_with_approve_transaction_hash(
            sort_key, user_id, approve_transaction_hash)

        # token_send_table への書き込み完了後に出金関連の例外が発生した場合は、token_send_table のステータスを fail に更新する
        try:
            # relay 実施
            relay_transaction_hash = self.__relay(from_user_eth_address,
                                                  recipient_eth_address,
                                                  send_value,
                                                  transaction_count)
            self.__update_send_info_with_relay_transaction_hash(
                sort_key, user_id, relay_transaction_hash)
            # transaction の完了を確認
            is_completed = PrivateChainUtil.is_transaction_completed(
                relay_transaction_hash)
        except SendTransactionError as e:
            # ステータスを fail に更新し中断
            self.__update_send_info_with_send_status(sort_key, user_id, 'fail')
            raise e
        except ReceiptError:
            # send_value の値が残高を超えた場合や、処理最小・最大値の範囲に収まっていない場合に ReceiptError が発生するため
            # ValidationError として処理を中断する
            # ステータスを fail に更新
            self.__update_send_info_with_send_status(sort_key, user_id, 'fail')
            raise ValidationError('send_value')

        # transaction が完了していた場合、ステータスを done に更新
        if is_completed:
            self.__update_send_info_with_send_status(sort_key, user_id, 'done')

        return {
            'statusCode': 200,
            'body': json.dumps({'is_completed': is_completed})
        }
Esempio n. 29
0
    def exec_main_proc(self):
        ################
        # get parameter
        ################
        sort_key = TimeUtil.generate_sort_key()
        from_user_eth_address = self.event['requestContext']['authorizer'][
            'claims']['custom:private_eth_address']
        user_id = self.event['requestContext']['authorizer']['claims'][
            'cognito:username']
        allowance = PrivateChainUtil.get_allowance(from_user_eth_address)
        transaction_count = PrivateChainUtil.get_transaction_count(
            from_user_eth_address)

        ################
        # validation
        ################
        # validate raw_transaction
        # init_approve_signed_transaction
        if int(allowance, 16) != 0:
            # allowance が設定されている場合は必須
            if self.params.get('init_approve_signed_transaction') is None:
                raise ValidationError(
                    'init_approve_signed_transaction is invalid.')
            # data
            init_approve_data = PrivateChainUtil.get_data_from_raw_transaction(
                self.params['init_approve_signed_transaction'],
                transaction_count)
            PrivateChainUtil.validate_erc20_approve_data(init_approve_data)
            if int(init_approve_data[72:], 16) != 0:
                raise ValidationError('Value of init_approve is invalid.')
            transaction_count = PrivateChainUtil.increment_transaction_count(
                transaction_count)

        # approve_signed_transaction
        approve_data = PrivateChainUtil.get_data_from_raw_transaction(
            self.params['approve_signed_transaction'], transaction_count)
        PrivateChainUtil.validate_erc20_approve_data(approve_data)
        # 日次の限度額を超えていた場合は例外
        sum_price = self.__get_token_send_value_today(user_id)
        if Decimal(os.environ['DAILY_LIMIT_TOKEN_SEND_VALUE']
                   ) < sum_price + Decimal(int(approve_data[72:], 16)):
            raise ValidationError('Token withdrawal limit has been exceeded.')
        transaction_count = PrivateChainUtil.increment_transaction_count(
            transaction_count)

        # relay_signed_transaction
        relay_data = PrivateChainUtil.get_data_from_raw_transaction(
            self.params['relay_signed_transaction'], transaction_count)
        PrivateChainUtil.validate_erc20_relay_data(relay_data)
        # approve と relay の value が同一であること
        approve_value = int(approve_data[72:], 16)
        relay_value = int(relay_data[72:], 16)
        if approve_value != relay_value:
            raise ValidationError('approve and relay values do not match.')

        #######################
        # send_raw_transaction
        #######################
        # 既に approve されている場合(allowance の戻り値が 0 ではない場合)、該当の approve を削除する(0 で更新)
        if int(allowance, 16) != 0:
            PrivateChainUtil.send_raw_transaction(
                self.params.get('init_approve_signed_transaction'))

        # approve 実施
        approve_transaction_hash = PrivateChainUtil.send_raw_transaction(
            self.params.get('approve_signed_transaction'))
        self.__create_send_info_with_approve_transaction_hash(
            sort_key, user_id, approve_transaction_hash, relay_value)

        # token_send_table への書き込み完了後に出金関連の例外が発生した場合は、token_send_table のステータスを fail に更新する
        try:
            # relay 実施
            relay_transaction_hash = PrivateChainUtil.send_raw_transaction(
                self.params.get('relay_signed_transaction'))
            self.__update_send_info_with_relay_transaction_hash(
                sort_key, user_id, relay_transaction_hash)
            # transaction の完了を確認
            is_completed = PrivateChainUtil.is_transaction_completed(
                relay_transaction_hash)
        except SendTransactionError as e:
            # ステータスを fail に更新し中断
            self.__update_send_info_with_send_status(sort_key, user_id, 'fail')
            raise e
        except ReceiptError:
            # send_value の値が残高を超えた場合や、処理最小・最大値の範囲に収まっていない場合に ReceiptError が発生するため
            # ValidationError として処理を中断する
            # ステータスを fail に更新
            self.__update_send_info_with_send_status(sort_key, user_id, 'fail')
            raise ValidationError('send_value')

        # transaction が完了していた場合、ステータスを done に更新
        if is_completed:
            self.__update_send_info_with_send_status(sort_key, user_id, 'done')

        return {
            'statusCode': 200,
            'body': json.dumps({'is_completed': is_completed})
        }