Example #1
0
    def get(self, id):
        """Get all data, getall
        """
        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            for k, v in field_inputs.items():
                field_inputs[k]['required'] = False

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[__heads__] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        if not hasattr(g, 'user'):
            return omitError('CE_NOT_EXIST', 'not login yet'), 400

        r = g.user
        if r is None:
            return omitError('CE_NOT_EXIST'), 400

        # 1.1 check permission
        if r.id != id:
            return omitError('CE_UNAUTHORIZED', 'id not match'), 400

        # 2. export to user
        _r = dict((col, getattr(r, col)) for col in r.__table__.columns.keys())
        self.args[field_inputs_wrap_head] = _r

        _resource_fields = resource_fields.copy()
        _resource_fields_wrap = resource_fields_wrap.copy()
        for col in resource_fields_wrap:
            if col not in ['type', 'subtype']:
                _resource_fields_wrap.pop(col, None)

        _resource_fields.pop('access_token', None)
        _resource_fields_wrap[field_inputs_wrap_head] = (
            fields.Nested(_resource_fields))
        self.args['type'] = "system"
        self.args['subtype'] = "regist"
        return marshal(self.args, _resource_fields_wrap), 200
Example #2
0
    def get(self):
        """Get all data
        """
        # one to many
        # 1. parsing reqest
        try:
            # FIXME:
            # when i assign field_inputs['name']['required'] to True,
            # it could through below error:
            # ValueError: [name]: (name Valid Error) Missing required parameter
            # in dataDict
            # but i have no idea what it happen.
            if os.environ.get('EVN'):
                # in unit test
                field_inputs['name']['required'] = False
                logger.warning('now we are in unit test mode, turn off'\
                               ' field_inputs[\'name\'][\'required\']'\
                               ' but 1st run is ok :(')

            self.args = GetRequest(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[__heads__] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(grp, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        r = grp.query.order_by(isDesc())
        _r = r.all()
        self.args['total'] = len(_r)

        if itemsPerPage is not 0:
            _r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()
        r = _r

        # 2. export to user
        data, field = SerialGroupOutput(r,
                                        resource_fields=resource_fields,
                                        omitKeys=['id', 'name'])
        self.args[__heads__] = data

        _resource_fields_wrap = resource_fields_wrap.copy()
        _resource_fields_wrap[__heads__] = fields.List(fields.Nested(field))

        return marshal(self.args, _resource_fields_wrap), 200
Example #3
0
    def get(self, id):
        """Get all data, getall
        """
        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            for k, v in field_inputs.items():
                field_inputs[k]['required'] = False

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[__heads__] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        r = obj.query.filter(obj.id == id, obj.isdel == False).scalar()
        if r is None:
            return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400

        # 2. export to user
        _r = dict((col, getattr(r, col)) for col in r.__table__.columns.keys())
        self.args[field_inputs_wrap_head] = _r

        _resource_fields = resource_fields.copy()
        _resource_fields_wrap = resource_fields_wrap.copy()
        for col in resource_fields_wrap:
            if col not in ['type', 'subtype']:
                _resource_fields_wrap.pop(col, None)

        _resource_fields_wrap[field_inputs_wrap_head] = (
            fields.Nested(_resource_fields))
        self.args['type'] = "business"
        self.args['subtype'] = "rate"
        return marshal(self.args, _resource_fields_wrap), 200
Example #4
0
    def get(self):
        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(__heads__, 'refBy')
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        try:
            self.args = _reqparse.parse_args()
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())
            self.args[__heads__] = []

        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())
            return omitError('CE_INVALID_PARAM', repr(error)), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(obj, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        # .order_by(User.login.desc())
        r = obj.query.order_by(isDesc())

        if itemsPerPage is 0:
            r = r.all()
        else:
            r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()
        for _r in r:
            __r = dict(
                (col, getattr(_r, col)) for col in _r.__table__.columns.keys())
            self.args[__heads__].append(__r)

        self.args['total'] = len(r)

        _resource_fields_wrap[__heads__] = {}
        _resource_fields_wrap[__heads__] = fields.List(
            fields.Nested(resource_fields))
        return marshal(self.args, _resource_fields_wrap), 200
Example #5
0
    def output(self, key, obj):
        value = get_value(key if self.attribute is None else self.attribute,
                          obj)
        if value is None:
            if self.allow_null:
                return None
            elif self.default is not None:
                return self.default

        return marshal(value, self.nested)
Example #6
0
    def output(self, key, data):
        value = get_value(key if self.attribute is None else self.attribute,
                          data)
        # we cannot really test for external dict behavior
        if is_indexable_but_not_string(value) and not isinstance(value, dict):
            return self.format(value)

        if value is None:
            return self.default

        return [marshal(value, self.container.nested)]
Example #7
0
    def post(self):
        logger.debug('request.header: \n%s', request.headers)

        login = request.headers.get('login')
        passHash = request.headers.get('passHash')
        Authentication = request.headers.get('Authentication')

        if not login or not passHash or not Authentication:
            return omitError(ErrorMsg=\
                    'Not Found: login(%s)/passHash(%s)/Authentication(%s)' %
                        ( login, passHash, Authentication)
                    ), 400
        elif ('SAGITTARIUS' not in Authentication):
            return omitError(ErrorMsg='SAGITTARIUS not in Authentication header(%s)'\
                    % Authentication), 400

        user = Users.get_by_loginpass(login, passHash)

        if not user:
            logger.debug("user %s not found with password %s", login, passHash)
            #return omitError(ErrorMsg='not Authentication ), 401
            abort(401)
        #elif not Users.sign(user.id, login, passHash):
        #    logger.debug("Users.sign fail")
        #    return omitError(ErrorMsg='not Authentication ), 401
        else:
            if user.passHash == "":  # no passHash, not use email to login
                logger.debug(
                    "user %s not found with password %s, use non email login",
                    login, passHash)
                abort(401)
            self.args, _resource_fields_wrap = signin(user)
            #            g.user = user
            #            _resource_fields = {}
            #            _resource_fields_wrap = resource_fields_wrap.copy()
            #            for col in resource_fields_wrap:
            #                if col not in ['type', 'subtype']:
            #                    _resource_fields_wrap.pop(col, None)
            #
            #            _resource_fields_wrap[field_inputs_wrap_head] = fields.Nested(resource_fields)
            #
            #            self.args = {}
            #            self.args[field_inputs_wrap_head] = dict((col, getattr(user, col)) for col in user.__table__.columns.keys())
            #            #self.args[field_inputs_wrap_head]['sid'] = session['sid']
            #            token = user.generate_auth_token()
            #            self.args[field_inputs_wrap_head]['access_token'] = token.decode('ascii')
            #            self.args[field_inputs_wrap_head]['clientIp'] = request.environ['REMOTE_ADDR']
            #
            #            logger.debug("self.args[field_inputs_wrap_head]: %s", self.args[field_inputs_wrap_head])
            #            self.args['type'] = "admin"
            #            self.args['subtype'] = "login"
            return marshal(self.args, _resource_fields_wrap), 200
Example #8
0
    def get(self, id):
        """
            retreive one record
        """
        r = grp.query.filter(grp.id == id).scalar()

        if r is None:
            return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400

        data, field = SerialGroupOutput(r, resource_fields=resource_fields,
                omitKeys=['id', 'name'])

        return marshal(data, field), 200
Example #9
0
    def put(self, id):
        requestArgsSet = set((col) for col in request.args)
        if not ExtraParamsIsValid(requestArgsSet):
            return omitError(ErrorMsg=repr(set(
                (col) for col in request.args))), 400

        try:
            self.dataDict = request.get_json()
            request.dataDict = self.dataDict[__head__]
            add_argument(_reqparse, field_inputs)
            self.args = _reqparse.parse_args()
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            if error == type(BadRequest):
                return omitError(ErrorMsg='maybe json format error'), 400

            return omitError(ErrorMsg='{}'.format(repr(error.args))), 400

        try:
            checkInputIsValid(self.args)
        except Exception as error:
            return error.args

        r = obj.query.filter(obj.id == id).scalar()
        for k, v in self.args.items():
            if v != None:
                setattr(r, k, v)

        db.session.add(r)

        try:
            db.session.flush()
            db.session.commit()
        except Exception as error:
            db.session.rollback()
            logger.warning('session commit error(%s)', error)

            if exc.IntegrityError == type(error):
                return omitError('CE_NAME_CONFLICT', repr(error)), 400

            return omitError(ErrorMsg=repr(error)), 400

        self.args[__head__] = {}
        _resource_fields_wrap = {}
        _resource_fields_wrap[__head__] = fields.Nested(resource_fields)

        for col in r.__table__.columns.keys():
            self.args[__head__][col] = getattr(r, col)

        return marshal(self.args, _resource_fields_wrap), 200
Example #10
0
    def post(self):
        """Create new
        """
        # 1. parsing reqest
        try:
            self.args = GetRequest(__head__, field_inputs)
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        # 2. validate follows spec
        if db.session.query(grp.id).count() > max:
            return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400

        if len(self.args[__obj__heads__]) > childrenMax:
            return omitError('CE_EXCEED_LIMIT',
                             'limit is {}'.format(childrenMax)), 400

        # 3. assign request data to orm
        r = grp()
        try:
            r = PrepareGroupORM(r, obj, mapping, __obj__heads__,
                                self.args.items())
        except Exception as error:
            return omitError(ErrorMsg=repr(error)), 400

        # 4. commit to save
        try:
            db.session.add(r)
            db.session.flush()
            db.session.commit()
        except Exception as error:
            db.session.rollback()
            logger.warning('session commit error(%s)', error)

            if exc.IntegrityError == type(error):
                return omitError('CE_NAME_CONFLICT', repr(error)), 400

            return omitError(ErrorMsg=repr(error)), 400

        # 5. return all data to user
        data, field = SerialGroupOutput(r, resource_fields=resource_fields)

        return marshal(data, field), 200
Example #11
0
    def put(self, id):
        """
            update one record
        """
        # 1. parsing reqest
        try:
            self.args = GetRequest(__head__, field_inputs)
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        # 2. get orm from db
        r = grp.query.filter(grp.id == id).scalar()

        if r is None:
            return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400

        # 3. assign request data to orm
        try:
            r = PrepareGroupORM(r, obj, mapping, __obj__heads__,
                                self.args.items())
        except Exception as error:
            return omitError(ErrorMsg=repr(error)), 400

        # 4. commit to save
        try:
            db.session.merge(r)
            db.session.flush()
            db.session.commit()
        except Exception as error:
            db.session.rollback()
            logger.warning('session commit error(%s)', error)

            if exc.IntegrityError == type(error):
                return omitError('CE_NAME_CONFLICT', repr(error)), 400

            return omitError(ErrorMsg=repr(error)), 400

        # 5. return all data to user
        data, field = SerialGroupOutput(r, resource_fields=resource_fields)

        return marshal(data, field), 200
Example #12
0
    def get(self, id):

        requestArgsSet = set((col) for col in request.args)
        if not ExtraParamsIsValid(requestArgsSet):
            return omitError(ErrorMsg=repr(set(
                (col) for col in request.args))), 400

        r = obj.query.filter(obj.id == id).scalar()

        if r is None:
            return omitError('CE_NOT_EXIST',
                             'user id {} not found'.format(id)), 400

        self.args = {}
        self.args[__head__] = {}
        _resource_fields_wrap = {}
        _resource_fields_wrap[__head__] = fields.Nested(resource_fields)

        for col in r.__table__.columns.keys():
            self.args[__head__][col] = getattr(r, col)

        return marshal(self.args, _resource_fields_wrap), 200
Example #13
0
    def _put(self, id):
        #task = filter(lambda t: t['id'] == id, admins)
        #data = request.data
        #dataDict = json.loads(data)
        #parser = reqparse.RequestParser()
        #parser.add_argument('login', required=True, type=str, location=['json', 'form', 'values'], help='Rate cannot be converted')
        #args = parser.parse_args()
        #print(data, 'xxx', 'dataDict', self.dataDict, 'xxx', args)
        #print(self.dataDict, 'xxx')
        #if len(task) == 0:
        #    abort(404)
        try:
            args = _reqparse.parse_args()
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())
            message['message'] = ' '.join(error.args)
            return message, 400

        #task = {}
        #print(args, 'xxxx')
        #r = User.query.filter(
        #        User.id == id).options(lazyload('AdminGroup').first()
        # one to many
        r = UsersMAdminGroup.query.filter(UsersMAdminGroup.user_id == id).all()
        #print(_r.user_obj.login, 'xxxx')
        #r = User.query.filter(
        #        User.id == id).first()

        #rr = UsersMAdminGroup.query.filter(
        #        UsersMAdminGroup.user_id == id).all()

        if len(r) is 0:
            message['message'] = 'user id {} not found'.format(id)
            return message, 400

        else:
            for k, v in args.items():
                if v != None:
                    if k == 'admingroup':
                        continue

                    #print(k, v, 'v', type(v) is dict, type(v))
                    setattr(r[0].user_obj, k, v)

                    #data = json.loads(repr(v))
            db.session.add(r[0].user_obj)

            # update foreign table
        # delete all mapping
        if args['admingroup']:
            #print("args['admingroup']",
            #        json.loads(args['admingroup'][1].replace('\'', '"')))
            try:

                for _r in r:
                    # 1. delete all
                    db.session.delete(_r)

                db.session.flush()

                for entity in args['admingroup']:
                    # 2. re-add it
                    rr = UsersMAdminGroup()
                    rr.admingroup_id = json.loads(
                        (entity.replace('\'', '"'))).get('id')
                    rr.user_id = id
                    db.session.add(rr)
                #print(json.loads(args['admingroup'].replace('\'', '"')))
                #print(set((col) for col in json.loads(args['admingroup'].replace('\'', '"')).get('id')))
                #for admingroup_id in json.loads(args['admingroup'].replace('\'', '"')).get('id')
                #rr = UsersMAdminGroup()
                #rr.admingroup_id = admingroup_id
                #rr.user_id = id
                #db.session.add(rr)

                #j = repr(args['admingroup'])
                #j = re.sub(r"{\s*(\w)", r'{"\1', j)
                #j = re.sub(r",\s*(\w)", r',"\1', j)
                #j = re.sub(r"(\w):", r'\1":', j)
                #admingroup = json.loads(j)
                #admingroup = json.loads(args['admingroup'].replace('\'', '"'))
                #admingroup = json.loads(repr(args['admingroup']))
                #admingroup = json.loads(('{"id": "1"}'))
                #print('rr', type(args['admingroup']), type(admingroup), repr(args['admingroup']))
                #admingroup_id = admingroup[0].get('id')
                # JSON requires double quotes for its strings.
                #admingroup_id = json.loads(args['admingroup'].replace('\'', '"')).get('id')
                #if admingroup_id:

                #    #print(rr, 'rr', admingroup_id)
                #    if rr is None:
                #        rr = UsersMAdminGroup()
                #        rr.admingroup_id = admingroup_id
                #        rr.user_id = id
                #        db.session.add(rr)

                #    #print(json.loads(repr(args['admingroup'])).get('id'), 'd')
                #    #setattr(rr, 'user_id', json.loads(repr(args['admingroup'])).get('id'))
            except Exception as error:
                # for ambiguous
                #(TypeError, ValueError) as err:
                logger.debug('impossible that parsing json %s error(%s)',
                             args['admingroup'], error)
                pass
        #return message, 400

        #db.session.commit()
        try:
            db.session.commit()
        except Exception as error:
            logger.warning('session commit error(%s)', error)
            db.session.rollback()
            return message, 400

        #print(dict((k, v['type']) for k,v in field_inputs.items()))
        # http://stackoverflow.com/questions/7389759/memory-efficient-built-in-sqlalchemy-iterator-generator
        #args['admingroup'] = dict(('id', getattr(_r,'id')) for _r in rr)
        #r = UsersMAdminGroup.query.filter(UsersMAdminGroup.user_id == id) \
        #    .with_entities(UsersMAdminGroup.admingroup_id).all()
        #r = UsersMAdminGroup.query.filter(
        #        UsersMAdminGroup.user_id == id).with_entities(UsersMAdminGroup.user_id,
        #                UsersMAdminGroup.admingroup_id).all()
        r = UsersMAdminGroup.query.filter(UsersMAdminGroup.user_id == id).all()

        for col in r[0].user_obj.__table__.columns.keys():
            args[col] = getattr(r[0].user_obj, col)

        args['admingroup'] = []
        for _r in r:
            args['admingroup'].append({'id': getattr(_r, 'admingroup_id')})

        # http://stackoverflow.com/questions/15261149/sqlalchemy-how-is-it-that-a-comma-determines-if-a-query-returns-a-string-or-a-t
        #for _r, in r:
        #    args['admingroup'].append({'id': _r})
        #args['admingroup'].append( \
        #    dict((col, getattr(_r, col))
        #            for col in _r.__table__.columns.keys() if col is not 'id'))
        #print(dict((col, getattr(_r, col)) for col in _r.__table__.columns.keys()))
        #print(dict((col, getattr(_r, col)) for col in _r.__table__.columns.keys() if col is not 'id'))

        #return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}

        #return message, 200
        return marshal(args, resource_fields), 200
Example #14
0
    def get(self):
        """Get all data, getall

         @api {get} /rest/objects/ipaddrs Read IP Addresses
         @apiVersion 0.0.1
         @apiName GetIpAddrs
         @apiVersion 0.0.1
         @apiGroup objects
         @apiPermission registered user
         
         @apiDescription
         todo validation
         
         @apiParam {Number=0, 25, 50, 100} [itemsPerPage=25] items for each request.
         @apiParam {Number} [page=1] page you want to request from, start with 1.
         @apiParam {String="name", "description"} [orderBy=name] the items order by column you specified.
         @apiParam {String="true", "false"} [desc=false] the items order by descending or asceding order.

         
         @apiExample Example usage:
         curl -i http://localhost/rest/objects/ipaddrs?itemsPerPage=50&page=1&orderBy=name&desc=true
         
         @apiSuccess {Number}   total         total items for pagination.
         @apiSuccess {String}   orderBy       the items order by column you specified.
         @apiSuccess {Number}   page          page you want to request from, start with 1.
         @apiSuccess {Number}   itemsPerPage  items for each request.
         @apiSuccess {String}   desc          the items order by descending or asceding order.
         @apiSuccess {Object[]} ipaddrs       List of IP Addresses.
         @apiSuccess {String}   ipaddrs.addr1 1st IP Address.
         @apiSuccess {String}   ipaddrs.addr2 2ed IP Address.
         @apiSuccess {String}   ipaddrs.description this items's description.
         @apiSuccess {Number}   ipaddrs.id index in database.
         @apiSuccess {String}   ipaddrs.ipVersion IP Address version.
         @apiSuccess {String}   ipaddrs.name items uniq name for record.
         @apiSuccess {String}   ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'.

         @apiError CE_INVALID_PARAM invalid parameter
         @api {get} /rest/objects/ipaddrs
         @apiErrorExample {json} we use invalid parameter pages
            curl -i http://localhost/rest/objects/ipaddrs?pages=1
            ================================================
             HTTP/1.0 400 BAD REQUEST
            {
                "errorId": 2001,
                "message": "{'pages'}"
            }
        """
        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            # FIXME:
            # when i assign field_inputs['name']['required'] to True,
            # it could through below error:
            # ValueError: [name]: (name Valid Error) Missing required parameter
            # in dataDict
            # but i have no idea what it happen.
            if os.environ.get('EVN'):
                # in unit test
                field_inputs['name']['required'] = False
                logger.warning('now we are in unit test mode, turn off'\
                               ' field_inputs[\'name\'][\'required\']'\
                               ' but 1st run is ok :(')

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[__heads__] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(obj, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        r = obj.query.order_by(isDesc())
        _r = r.all()
        self.args['total'] = len(_r)

        if itemsPerPage is not 0:
            _r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()

        r = _r
        # 2. export to user
        for _r in r:
            __r = dict(
                (col, getattr(_r, col)) for col in _r.__table__.columns.keys())
            self.args[__heads__].append(__r)

        resource_fields_wrap[__heads__] = fields.List(
            fields.Nested(resource_fields))
        return marshal(self.args, resource_fields_wrap), 200
Example #15
0
    def get(self, id):
        """
        @api {get} /rest/objects/ipaddr/:id get one IP address item.
        @apiName GetIpAddr
        @apiVersion 0.0.1
        @apiGroup objects
        @apiPermission registered user
        
        @apiDescription
        todo validation
        
        @apiParam {Number} id IP Address item id.

        @apiExample Example usage:
        curl -i http://localhost/rest/objects/ipaddr/7
         
        @apiSuccess {Object[]} ipaddrs       List of IP Addresses.
        @apiSuccess {String}   ipaddrs.addr1 1st IP Address.
        @apiSuccess {String}   ipaddrs.addr2 2ed IP Address.
        @apiSuccess {String}   ipaddrs.description this items's description.
        @apiSuccess {Number}   ipaddrs.id index in database.
        @apiSuccess {String}   ipaddrs.ipVersion IP Address version.
        @apiSuccess {String}   ipaddrs.name items uniq name for record.
        @apiSuccess {String}   ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'.

        @apiError CE_INVALID_PARAM invalid parameter
        @api {get} /rest/objects/ipaddr/:id
        @apiErrorExample {json} we use invalid parameter pages
            curl -X GET -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/7?pages=1
            ================================================
            HTTP/1.0 400 BAD REQUEST
           {
               "errorId": 2001,
               "message": "{'pages'}"
           }
        
        @apiError CE_NOT_EXIST item not found
        @api {get} /rest/objects/ipaddr/:id
        @apiErrorExample {json} we use not exist id
            curl -X GET -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/17
            ================================================
            HTTP/1.0 400 BAD REQUEST
           {
               "errorId": 2003,
               "message": "id 17 not found"
           }

        """
        requestArgsSet = set((col) for col in request.args)
        if not ExtraParamsIsValid(requestArgsSet):
            return omitError(ErrorMsg=repr(set(
                (col) for col in request.args))), 400

        r = obj.query.filter(obj.id == id).scalar()

        if r is None:
            return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400

        self.args = {}
        self.args[__head__] = {}
        _resource_fields_wrap = {}
        _resource_fields_wrap[__head__] = fields.Nested(resource_fields)

        for col in r.__table__.columns.keys():
            self.args[__head__][col] = getattr(r, col)

        return marshal(self.args, _resource_fields_wrap), 200
Example #16
0
    def post(self):
        try:
            self.dataDict = request.get_json()
            request.dataDict = self.dataDict[__head__]
            add_argument(_reqparse, field_inputs)
            args = _reqparse.parse_args()
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            if error == type(BadRequest):
                return omitError(ErrorMsg='maybe json format error'), 400

            return omitError(ErrorMsg='{}'.format(error.args)), 400

        if db.session.query(obj.id).count() > limit['max']:
            return omitError('CE_EXCEED_LIMIT',
                             'limit is {}'.format(limit['max'])), 400

        try:
            # now we only support IPv4/IPv6
            args['addr1'] = inputs.is_ipv4_ipv6(args['addr1'],
                                                argument=args['ipVersion'])
        except socket.error as error:
            # Not legal
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())
            return omitError(
                'CE_INVALID_PARAM',
                '`{}/{}`: {}'.format(args['addr1'], args['ipVersion'],
                                     error.args)), 400

        ip = args['addr1']
        ver = args['ipVersion']
        pre = args['addr2']

        try:
            if args['type'] == 'Single':
                # TODO: maybe we limit that could not pass anything in attribute 'addr2'
                pass

            elif args['type'] == 'Range':
                # do the same as below
                pre = inputs.is_ipv4_ipv6(pre, argument=ver)
                # legal
            elif args['type'] == 'Subnet':
                # do the same as below
                if 'IPv4' == ver:
                    #NOTICE: maybe correct user's input?
                    try:
                        ip = inputs.is_cidr(ip, argument=pre)
                    except Exception as error:
                        pre = inputs.is_netmask(pre)

                elif 'IPv6' == ver:
                    pre = inputs.is_ipv6_prefix(ip, argument=pre)
                # legal

        except Exception as error:
            # Not legal
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())
            return omitError('CE_INVALID_PARAM', '`{}/{}({})`: {}'.\
                    format(ip, pre, ver, error.args)), 400

        r = obj()
        for k, v in args.items():
            if v != None:
                setattr(r, k, v)

        db.session.add(r)

        try:
            db.session.flush()
            db.session.commit()
        except Exception as error:
            db.session.rollback()
            logger.warning('session commit error(%s)', error)

            if exc.IntegrityError == type(error):
                return omitError('CE_NAME_CONFLICT', repr(error)), 400

            return omitError(ErrorMsg=repr(error)), 400

        # get id immediately after call commit
        for col in r.__table__.columns.keys():
            args[col] = getattr(r, col)

        args[__head__] = args
        _resource_fields = {}
        _resource_fields[__head__] = fields.Nested(resource_fields)
        return marshal(args, _resource_fields), 200
Example #17
0
    def get(self):
        """Get all data, getall

        @api {get} /rest/customer/businesses list business
        @apiName GetAllCustomerBusinesses
        @apiVersion 0.0.3
        @apiGroup business
        @apiPermission registered user

        @apiDescription
        modified: change category type from string to number.<br/>
        modified: add name attribute.<br />
        modified: change deal type from string to number.<br/>
        todo validation<br/>
        query string <br />
        todo error / success return code in api <br />

        @apiParam {Number=0, 25, 50, 100} [itemsPerPage=25] items for each request.
        @apiParam {Number} [page=1] page you want to request from, start with 1.
        @apiParam {String="name", "description"} [orderBy=name] the items order by column you specified.
        @apiParam {String="true", "false"} [desc=false] the items order by descending or asceding order.


        @apiExample {curl} Example usage:
        curl -X GET -H "mTag: xx" -H "Content-Type:application/json" -i http://localhost/rest/customer/businesses?itemsPerPage=50&page=1&orderBy=name&desc=true

        {  
            "page":1,
            "type":"business",
            "orderBy":"name",
            "desc":0,
            "total":1,
            "itemsPerPage":25,
            "subtype":"list",
            "data":[  
                {  
                    "lat":120.678,
                    "id":1,
                    "deal":200,
                    "name":"Starbucks Coffee 31",
                    "image_url":"",
                    "long":23.5383,
                    "cat":1,
                    "description":"early Bird Special: Get  off."
                }
            ]
        }

        @apiSuccess {Number}   total         total items for pagination
        @apiSuccess {String}   orderBy       the items order by column you specified
        @apiSuccess {Number}   page          page you want to request from, start with 1
        @apiSuccess {Number}   itemsPerPage  items for each request
        @apiSuccess {String}   desc          the items order by descending or asceding order
        @apiSuccess {String}   type          request's type
        @apiSuccess {String}   subtype       request's subtype
        @apiSuccess {Object}   business       object of business.
        @apiSuccess {Number}   business.id    item's uniq id.
        @apiSuccess {String}   business.name  item's name.
        @apiSuccess {Number}   business.cat   item's business industry category.
        @apiSuccess {float}    business.lat   item's entered latitude.
        @apiSuccess {float}    business.long  item's entered longitude.
        @apiSuccess {String}   business.address item's address
        @apiSuccess {String}   business.description item's description.
        @apiSuccess {Number}   business.deal  item's deal.
        @apiSuccess {String}   business.image_url  items's image url.


        @apiError CE_INVALID_PARAM invalid parameter
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2001,
            "message": "{'pages'}"
        }
        """
        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            for k, v in field_inputs.items():
                field_inputs[k]['required'] = False

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[field_inputs_wrap_head] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(obj, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        r = obj.query.filter(obj.isdel == False).order_by(isDesc())
        _r = r.all()
        self.args['total'] = len(_r)

        if itemsPerPage is not 0:
            _r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()

        r = _r
        # 2. export to user
        for _r in r:
            __r = dict(
                (col, getattr(_r, col)) for col in _r.__table__.columns.keys())
            #__r['description'] = getattr(_r.detail, 'description')

            # (1, 'icon'), (2, 'bg'), (3, 'gallery')
            ___r = pics.query.filter(pics.business_id == _r.id,
                                     pics.type == 1).scalar()
            __r['image_url'] = getattr(___r, 'path', "")
            self.args[field_inputs_wrap_head].append(__r)

        resource_fields_wrap[field_inputs_wrap_head] = fields.List(
            fields.Nested(resource_fields))
        self.args['type'] = "business"
        self.args['subtype'] = "list"
        return marshal(self.args, resource_fields_wrap), 200
Example #18
0
    def get(self, id):
        """Get all data, getall
        """
        """get pics by business id

        @api {get} /rest/pic/gallery/:id get pictures list with business id
        @apiVersion 0.0.5
        @apiName ListPicsUnderBusiness
        @apiGroup business
        @apiPermission registered user


        @apiDescription
        todo certificate with cookies / oauth 2.0<br />
        todo long/lat validation<br />
        todo metadata for counter of registerd devices<br />
        todo error / success return code in api

        @apiParam {Number} id business id
        @apiExample {curl} Example usage:
        curl -X GET -H "mTag: xx" -H "Content-Type:application/json" http://localhost/rest/pic/gallery/1
        {  
            "orderBy":"id",
            "itemsPerPage":25,
            "subtype":"gallery",
            "desc":0,
            "data":[  
                {  
                    "path":"/img/customer/1/BYTPH2_20160618_6615.jpg",
                    "id":5,
                    "width":1024,
                    "height":1365
                },
                {  
                    "path":"/img/customer/1/ZS0LII_10473.jpg",
                    "id":6,
                    "width":1024,
                    "height":1365
                },
                {  
                    "path":"/img/customer/1/G30SLL_20160618_6615.jpg",
                    "id":9,
                    "width":1024,
                    "height":1365
                }
            ],
            "type":"pic",
            "total":3,
            "page":1
        }

        @apiSuccess {Number}   total         total items in one business 
        @apiSuccess {String}   orderBy       the items order by column you specified
        @apiSuccess {Number}   page          page you want to request from, start with 1
        @apiSuccess {Number}   itemsPerPage  items for each request
        @apiSuccess {String}   type          request's type
        @apiSuccess {String}   subtype       request's subtype

        @apiSuccess {Object[]}   data       object

        @apiSuccess {Number}     data.id    image's id
        @apiSuccess {Number}     data.path  image's url that you could directly access
        @apiSuccess {Number}     data.height image's height(px)
        @apiSuccess {Number}     data.width image's width(px)
        """

        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            for k, v in field_inputs.items():
                field_inputs[k]['required'] = False

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[__heads__] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            #return omitError(ErrorMsg=repr(error)), 400
            return omitError('CE_INVALID_PARAM', 'not found'), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(obj, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        # FIXME: use mapping table
        r = obj.query.filter(obj.type == 3, obj.business_id == id,
                             obj.isdel == False).order_by(isDesc())
        _r = r.all()
        self.args['total'] = len(_r)

        if itemsPerPage is not 0:
            _r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()

        r = _r
        # 2. export to user
        self.args[field_inputs_wrap_head] = []
        for _r in r:
            __r = dict(
                (col, getattr(_r, col)) for col in _r.__table__.columns.keys())

            # FIXME: use mapping table
            if __r['type'] == 3:
                rest_pic_prefix = os.path.join(REST_PIC_PREFIX, 'customer',
                                               str(__r['business_id']))
                __r['path'] = os.path.join(rest_pic_prefix, __r['path'])
                self.args[field_inputs_wrap_head].append(__r)

        _resource_fields_wrap = resource_fields_wrap.copy()
        _resource_fields_wrap.pop('gallery_nr', None)
        _resource_fields_wrap[field_inputs_wrap_head] = fields.List(
            fields.Nested(resource_fields_post))

        self.args['type'] = "pic"
        self.args['subtype'] = "gallery"

        return marshal(self.args, _resource_fields_wrap), 200
Example #19
0
    def get(self, id):
        """get all devices info by business id

        @api {get} /rest/pushno/reg/:id registed devices under business id
        @apiVersion 0.0.4
        @apiName GetAllDeviceByBusinessId
        @apiGroup pushno
        @apiPermission registered user

        @apiParam {Number} id business id, you can get from GetAllCustomerBusinesses.

        @apiDescription
        todo certificate with cookies / oauth 2.0<br />
        todo long/lat validation<br />
        todo metadata for counter of registerd devices<br />
        todo error / success return code in api

        @apiExample {curl} Example usage:

        curl -X GET -H "mTag: xx" -H "Content-Type:application/json" http://localhost/rest/pushno/reg/1

        {  
            "orderBy":"user_id",
            "desc":0,
            "subtype":"reg",
            "itemsPerPage":25,
            "page":1,
            "data":[  
                {  
                    "dev_id":"eh2AM5l18K8:APA91bFsjAU_FmdkdTeErJ_BRSiz7_Iipi_r12QTscHciTVJmj1gcSK_p9l6BfgYtudntv0Ht7JNiyCe8lS-WdrL8zHOwCdGFdRutEDglPV1I9EeROVbhwVX0rcd_PS_jdCTQZ22inFq",
                    "id":4,
                    "user_id":1,
                    "business_id":1,
                    "type":1
                },
                {  
                    "dev_id":"eh2AM5l18K8:APA91bFsjAU_FmdkdTeErJ_BRSiz7_Iipi_r12QTscHciTVJmj1gcSK_p9l6BfgYtudntv0Ht7JNiyCe8lS-WdrL8zHOwCdGFdRutEDglPV1I9EeROVbhwVX0rcd_PS_jdCTQZ22inFq",
                    "id":5,
                    "user_id":1,
                    "business_id":1,
                    "type":1
                },
                {  
                    "dev_id":"eh2AM5l18K8:APA91bFsjAU_FmdkdTeErJ_BRSiz7_Iipi_r12QTscHciTVJmj1gcSK_p9l6BfgYtudntv0Ht7JNiyCe8lS-WdrL8zHOwCdGFdRutEDglPV1I9EeROVbhwVX0rcd_PS_jdCTQZ22inFq",
                    "id":6,
                    "user_id":1,
                    "business_id":1,
                    "type":1
                }
            ],
            "total":3,
            "type":"pushno"
        }

        @apiSuccess {Number}   total         total items for pagination
        @apiSuccess {String}   orderBy       the items order by column you specified
        @apiSuccess {Number}   page          page you want to request from, start with 1
        @apiSuccess {Number}   itemsPerPage  items for each request
        @apiSuccess {String}   desc          the items order by descending or asceding order
        @apiSuccess {String}   type          request's type

        @apiSuccess {Object[]}   devices       object of devices
        @apiSuccess {Number}     devices.id    device's uniq id
        @apiSuccess {Number}     devices.user_id registered user id
        @apiSuccess {Number=1, 2}devices.type    device's type, 1 for andriod, 2 for ios
        @apiSuccess {String{..254}}   devices.dev_id  device's id
        """

        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            for k, v in field_inputs.items():
                field_inputs[k]['required'] = False

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[field_inputs_wrap_head] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(obj, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        r = obj.query.filter(obj.business_id == id,
                             obj.isdel == False).order_by(isDesc())
        _r = r.all()
        self.args['total'] = len(_r)

        if itemsPerPage is not 0:
            _r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()

        r = _r
        # 2. export to user
        for _r in r:
            __r = dict(
                (col, getattr(_r, col)) for col in _r.__table__.columns.keys())
            self.args[field_inputs_wrap_head].append(__r)

        _resource_fields = resource_fields.copy()
        _resource_fields_wrap = resource_fields_wrap.copy()
        _resource_fields_wrap[field_inputs_wrap_head] = fields.List(
            fields.Nested(_resource_fields))
        self.args['type'] = "pushno"
        self.args['subtype'] = "reg"
        return marshal(self.args, _resource_fields_wrap), 200
Example #20
0
    def get(self):
        """google / fb
        """
        # fix route hardcode
        _request = request.args.get('q', None)
        code = request.args.get('code', None)
        access_token = request.args.get('access_token', None)
        logger.debug("login code %s, q=%s access_token=%s", code, _request,
                     access_token)
        if 1:  # for debug
            if not access_token:
                return omitError('CE_UNAUTHORIZED',
                                 'no route, permission deny'), 400

            if _request == 'google' or request.path == '/rest/admin/login/google':
                oauth = OAuthSignIn.get_provider('google')
                userinfo = oauth.get_session(access_token=access_token)
                user = Users.regist_by_google(userinfo)
                #log the user in-->
                #HERE YOU LOG THE USER IN, OR ANYTHING ELSE YOU WANT
                #THEN REDIRECT TO PROTECTED PAGE
                self.args, _resource_fields_wrap = signin(user)
                return marshal(self.args, _resource_fields_wrap), 200
            elif _request == 'facebook' or request.path == '/rest/admin/login/facebook':
                resp = urllib.request.Request(
                    settings.FACEBOOK_OAUTH2_USERINFO_SCOPE +
                    "&access_token={accessToken}".format(
                        accessToken=access_token))
                #this gets the facebook profile!!
                content = None
                try:
                    with urllib.request.urlopen(resp) as _resp:
                        content = _resp.read()
                except urllib.error.URLError as e:
                    logger.debug(
                        'path %s, %s encounter urllib.error.URLError.reason %s',
                        resp.get_full_url(), resp, e.reason)
                    return omitError('CE_UNAUTHORIZED',
                                     ',, permission deny'), 400
                facebook_profile = json.loads(content.decode('utf-8'))
                print("facebook_profile  =", facebook_profile)

                userinfo = facebook_profile
                user = Users.regist_by_facebook(userinfo)
                #log the user in-->
                #HERE YOU LOG THE USER IN, OR ANYTHING ELSE YOU WANT
                #THEN REDIRECT TO PROTECTED PAGE
                self.args, _resource_fields_wrap = signin(user)
                return marshal(self.args, _resource_fields_wrap), 200

            return omitError('CE_UNAUTHORIZED',
                             'no route, permission deny'), 400

        else:
            #
            # the folloing are auto login without get access_token
            #
            if _request == 'google' or request.path == '/rest/admin/login/google':
                if code is None:  # request auth
                    # TODO: use OAuthSignIn.get_provider
                    logger.debug("login with google")
                    token_request_uri = settings.GOOGLE_OAUTH2_OAUTH2_URL
                    response_type = "code"
                    client_id = settings.GOOGLE_API_CLIENT_ID
                    redirect_uri = urllib.parse.urljoin(
                        request.url_root, '/rest/admin/login/google')
                    scope = settings.GOOGLE_API_SCOPE

                    url = "{token_request_uri}?response_type={response_type}&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}".format(
                        token_request_uri=token_request_uri,
                        response_type=response_type,
                        client_id=client_id,
                        redirect_uri=redirect_uri,
                        scope=scope)
                    return redirect(url)
                else:  #validate

                    login_failed_url = '/'
                    if 'error' in request.args or 'code' not in request.args:
                        logger.debug(
                            "'error' in request.args or 'code' not in request.args"
                        )
                        return omitError('CE_UNAUTHORIZED',
                                         'permission deny'), 400

                    access_token_uri = settings.GOOGLE_OAUTH2_TOKEN_URL
                    redirect_uri = urllib.parse.urljoin(
                        request.url_root, '/rest/admin/login/google')
                    #redirect_uri = request.url_root + '/rest/admin/login?q=google'
                    params = urllib.parse.urlencode({
                        'code':
                        code,
                        'redirect_uri':
                        redirect_uri,
                        'client_id':
                        settings.GOOGLE_API_CLIENT_ID,
                        'client_secret':
                        settings.GOOGLE_API_CLIENT_SECRET,
                        'grant_type':
                        'authorization_code'
                    })
                    print("params=", params)
                    params = params.encode('ascii')  # params should be bytes
                    headers = {
                        'content-type': 'application/x-www-form-urlencoded'
                    }
                    resp = urllib.request.Request(access_token_uri,
                                                  method='POST',
                                                  data=params,
                                                  headers=headers)
                    content = None
                    try:
                        with urllib.request.urlopen(resp) as _resp:
                            content = _resp.read()
                    except urllib.error.URLError as e:
                        logger.debug(
                            '%s encounter urllib.error.URLError.reason %s',
                            resp, e.reason)
                        return omitError('CE_UNAUTHORIZED',
                                         ', permission deny'), 400

                    token_data = json.loads(content.decode('utf-8'))
                    print("token_data=", token_data, ", content  =", content)
                    #session['access_token'] = token_data['access_token']

                    resp = urllib.request.Request(
                        settings.GOOGLE_OAUTH2_USERINFO +
                        "?access_token={accessToken}".format(
                            accessToken=token_data['access_token']))

                    try:
                        with urllib.request.urlopen(resp) as _resp:
                            content = _resp.read()
                    except urllib.error.URLError as e:
                        logger.debug(
                            '%s encounter urllib.error.URLError.reason %s',
                            resp, e.reason)
                        return omitError('CE_UNAUTHORIZED',
                                         ',, permission deny'), 400
                    #this gets the google profile!!
                    google_profile = json.loads(content.decode('utf-8'))
                    print("google_profile  =", google_profile)

                    oauth = OAuthSignIn.get_provider('google')
                    #session['access_token'] = 'ya29.Ci8VA43OwblUKzf7diCatoDGGuOn4untNZTKJNJ4VLkcj6wbA266u-eQd6qrRx3xWQ'
                    userinfo = oauth.get_session(
                        access_token=token_data['access_token'])
                    user = Users.regist_by_google(userinfo)
                    #log the user in-->
                    #HERE YOU LOG THE USER IN, OR ANYTHING ELSE YOU WANT
                    #THEN REDIRECT TO PROTECTED PAGE
                    self.args, _resource_fields_wrap = signin(user)
                    return marshal(self.args, _resource_fields_wrap), 200

            elif _request == 'facebook' or request.path == '/rest/admin/login/facebook':
                if code is None:  # request auth
                    # TODO: use OAuthSignIn.get_provider
                    logger.debug("login with facebook")
                    token_request_uri = settings.FACEBOOK_OAUTH2_OAUTH2_URL
                    client_id = settings.FACEBOOK_API_CLIENT_ID
                    redirect_uri = urllib.parse.urljoin(
                        request.url_root, '/rest/admin/login/facebook')
                    scope = settings.FACEBOOK_API_SCOPE
                    response_type = "code"

                    url = "{token_request_uri}?response_type={response_type}&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}".format(
                        token_request_uri=token_request_uri,
                        response_type=response_type,
                        client_id=client_id,
                        redirect_uri=redirect_uri,
                        scope=scope)

                    print("redirect url=", url)
                    return redirect(url)
                else:  #validate

                    login_failed_url = '/'
                    if 'error' in request.args or 'code' not in request.args:
                        logger.debug(
                            "'error' in request.args or 'code' not in request.args"
                        )
                        return omitError('CE_UNAUTHORIZED',
                                         'permission deny'), 400

                    access_token_uri = settings.FACEBOOK_OAUTH2_TOKEN_URL
                    redirect_uri = urllib.parse.urljoin(
                        request.url_root, '/rest/admin/login/facebook')
                    #redirect_uri = request.url_root + '/rest/admin/login?q=facebook'
                    params = urllib.parse.urlencode({
                        'code':
                        code,
                        'redirect_uri':
                        redirect_uri,
                        'client_id':
                        settings.FACEBOOK_API_CLIENT_ID,
                        'client_secret':
                        settings.FACEBOOK_API_CLIENT_SECRET,
                        'grant_type':
                        'authorization_code'
                    })
                    print("params=", params)
                    params = params.encode('ascii')  # params should be bytes
                    headers = {
                        'content-type': 'application/x-www-form-urlencoded'
                    }
                    resp = urllib.request.Request(access_token_uri,
                                                  method='POST',
                                                  data=params,
                                                  headers=headers)
                    content = None
                    try:
                        with urllib.request.urlopen(resp) as _resp:
                            content = _resp.read()
                    except urllib.error.URLError as e:
                        logger.debug(
                            '%s encounter urllib.error.URLError.reason %s',
                            resp, e.reason)
                        return omitError('CE_UNAUTHORIZED',
                                         ', permission deny'), 400

                    print(", content  =", content)
                    token_data = json.loads(content.decode('utf-8'))
                    print("token_data=", token_data, ", content  =", content)
                    #session['access_token'] = token_data['access_token']

                    resp = urllib.request.Request(
                        settings.FACEBOOK_OAUTH2_USERINFO_SCOPE +
                        "&access_token={accessToken}".format(
                            accessToken=token_data['access_token']))
                    #this gets the facebook profile!!

                    try:
                        with urllib.request.urlopen(resp) as _resp:
                            content = _resp.read()
                    except urllib.error.URLError as e:
                        logger.debug(
                            'path %s, %s encounter urllib.error.URLError.reason %s',
                            resp.get_full_url(), resp, e.reason)
                        return omitError('CE_UNAUTHORIZED',
                                         ',, permission deny'), 400
                    facebook_profile = json.loads(content.decode('utf-8'))
                    print("facebook_profile  =", facebook_profile)

                    #oauth = OAuthSignIn.get_provider('facebook')
                    ##session['access_token'] = 'ya29.Ci8VA43OwblUKzf7diCatoDGGuOn4untNZTKJNJ4VLkcj6wbA266u-eQd6qrRx3xWQ'
                    #userinfo = oauth.get_session(access_token=token_data['access_token'] )
                    userinfo = facebook_profile
                    user = Users.regist_by_facebook(userinfo)
                    #log the user in-->
                    #HERE YOU LOG THE USER IN, OR ANYTHING ELSE YOU WANT
                    #THEN REDIRECT TO PROTECTED PAGE
                    self.args, _resource_fields_wrap = signin(user)
                    return marshal(self.args, _resource_fields_wrap), 200

            return omitError('CE_UNAUTHORIZED',
                             'no route, permission deny'), 400
Example #21
0
    def get(self):
        """Get all data, getall

        @api {get} /rest/customer/comments list all comments
        @apiName GetAllCustomerComments
        @apiVersion 0.0.5
        @apiGroup campaign
        @apiPermission registered user


        @apiDescription
        todo validation<br/>
        todo query target<br/>

        @apiParam {Number=0, 25, 50, 100} [itemsPerPage=25] items for each request.
        @apiParam {Number} [page=1] page you want to request from, start with 1.
        @apiParam {String} [orderBy=mtime] the items order by column you specified.
        @apiParam {String="true", "false"} [desc=false] the items order by descending or asceding order.
        @apiParam {String={..254}} [q] query string for pre-defined columns.


        @apiExample {curl} Example usage:
        curl -X GET -H "mTag: xx" -H "Content-Type:application/json" http://localhost/rest/customer/comments

        HTTP/1.0 200 OK
        {  
            "page":1,
            "orderBy":"mtime",
            "desc":0,
            "total":2,
            "subtype":"comment",
            "type":"business",
            "itemsPerPage":25,
            "data":[  
                {  
                    "id":1,
                    "business_id":1,
                    "mtime":"2016-08-31 00:14:56.215613",
                    "content":"Starbucks were all over Singapore and the quality ",
                    "rate":2,
                    "user":{  
                        "id":2,
                        "avatar_url":""
                    }
                },
                {  
                    "id":2,
                    "business_id":1,
                    "mtime":"2016-08-31 04:23:15.682219",
                    "content":"Starbucks were all over Singapore and the quality ",
                    "rate":2,
                    "user":{  
                        "id":2,
                        "avatar_url":""
                    }
                }
            ]
        }

        @apiSuccess {Number}   total         total items for pagination.
        @apiSuccess {String}   orderBy       the items order by column you specified.
        @apiSuccess {Number}   page          page you want to request from, start with 1.
        @apiSuccess {Number}   itemsPerPage  items for each request.
        @apiSuccess {String}   desc          the items order by descending or asceding order.

        @apiSuccess {Object[]} data       List of business's comments.
        @apiSuccess {Number}   data.id    item's uniq id.
        @apiSuccess {String}   data.content  item's comment content
        @apiSuccess {Number}   data.rate   item's rate for business item
        @apiSuccess {Number}   data.mtime  items's latest modified time with ISO 8601 format
        @apiSuccess {Object}   data.user   item's author infomation
        @apiSuccess {Number}   data.user.id  item's author id
        @apiSuccess {String}   data.user.avatar_url  item's author avatar

        @apiError CE_INVALID_PARAM invalid parameter
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2001,
            "message": "{'pages'}"
        }

        @apiError CE_NOT_EXIST item not found
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2003,
            "message": "id 1 not found"
        }
        """
        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            for k, v in field_inputs.items():
                field_inputs[k]['required'] = False

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[field_inputs_wrap_head] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(obj, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        r = obj.query.filter(obj.isdel == False).order_by(isDesc())
        _r = r.all()
        self.args['total'] = len(_r)

        if itemsPerPage is not 0:
            _r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()

        r = _r
        # 2. export to user
        for _r in r:
            __r = dict(
                (col, getattr(_r, col)) for col in _r.__table__.columns.keys())
            ___r = db.session.query(Users).\
                    filter(_r.user_id == Users.id).scalar()
            __r['user'] = {'id': ___r.id, 'avatar_url': ___r.avatar_url}
            ___r = db.session.query(rates).\
                    filter(_r.user_id == rates.user_id, _r.business_id == rates.business_id).scalar()
            if ___r is not None:
                __r['rate'] = ___r.rate

            self.args[field_inputs_wrap_head].append(__r)

        _resource_fields = resource_fields.copy()
        _resource_fields_wrap = resource_fields_wrap.copy()
        _resource_fields['user'] = fields.Nested(resource_fields_user)
        _resource_fields_wrap[field_inputs_wrap_head] = fields.List(
            fields.Nested(_resource_fields))
        self.args['type'] = "business"
        self.args['subtype'] = "comment"
        return marshal(self.args, _resource_fields_wrap), 200
Example #22
0
    def get(self, id):
        """get one item

        @api {get} /rest/customer/business/:id get one business
        @apiName GetCustomerBusiness
        @apiVersion 0.0.4
        @apiGroup customer
        @apiPermission registered user

        @apiDescription
        todo validation<br />
        todo query target<br/>

        @apiParam {Number} id business id, you can get from GetAllCustomerBusinesses.

        @apiExample Example usage:
        HTTP/1.0 200 OK
        {
            "id": 1,
            "name": "Starbucks Coffee",
            "image_url": "/business/1/icon",
            "cat": 1,
            "deal": 200,
            "lat": 120.678469,
            "long": 23.538302,
            "description": "Early Bird Special: Get $2 off.",
            "detail": {
                "rate": 4.3,
                "rates": [
                    {"u_id": 1, "avatar_url": "/user/1/avater"},
                    {"u_id": 2, "avatar_url": "/user/2/avater"}
                ],
                "deals": [
                    {"title": "morning", "description": "for every one"}
                ],
                "open": "0600",
                "close": "2100",
                "dist": 12333333,
                "address": "CA",
                "images_url": {
                    "bg": "/business/1/bg",
                    "icon": "/business/1/icon"
                }
            }
        }



        @apiSuccess {Object}     business       object of business.
        @apiSuccess {Number}     business.id    item's uniq id.
        @apiSuccess {String}     business.name  item's name.
        @apiSuccess {Number}     business.cat   item's business industry category.
        @apiSuccess {float}      business.lat   item's entered latitude.
        @apiSuccess {float}      business.long  item's entered longitude.
        @apiSuccess {String}     business.address item's address
        @apiSuccess {String}     business.description item's description.
        @apiSuccess {Number}     business.deal  item's deal.
        @apiSuccess {String}     business.image_url  items's image url.
        @apiSuccess {Object}     business.detail item's detail
        @apiSuccess {Float}      business.detail.rate item's rate, average from each comments
        @apiSuccess {Object[]}   business.detail.rates item's brief comments 
        @apiSuccess {Number}     business.detail.rates.u_id comment's author id
        @apiSuccess {String}     business.detail.rates.avatar_url comment's author avatar url path
        @apiSuccess {Object[]}   business.detail.deals item's deals
        @apiSuccess {String}     business.detail.deals.title item's deal title
        @apiSuccess {String}     business.detail.deals.description item's deal description
        @apiSuccess {String}     business.detail.open item open time with 24h format
        @apiSuccess {String}     business.detail.open item close time with 24h format
        @apiSuccess {Number}     business.detail.dist item's distance farward with your current location, the unit is meter
        @apiSuccess {Object}     business.detail.images_url item images' path
        @apiSuccess {String}     business.detail.images_url.bg item backgound images' path
        @apiSuccess {String}     business.detail.images_url.icon item icon images' path



        @apiError CE_INVALID_PARAM invalid parameter
        HTTP/1.0 400 BAD REQUEST
        {
           "errorId": 2001,
           "message": "{'pages'}"
        }

        @apiError CE_NOT_EXIST item not found
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2003,
            "message": "id 17 not found"
        }

        """
        requestArgsSet = set((col) for col in request.args)
        if not ExtraParamsIsValid(requestArgsSet):
            return omitError(ErrorMsg=repr(set(
                (col) for col in request.args))), 400

        r = detail.query.filter(detail.business_id == id,
                                detail.isdel == False).scalar()

        if r is None:
            return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400

        self.args = {}
        self.args[field_inputs_wrap_head] = {}
        #self.args[field_inputs_wrap_head][__head_detail__] = {}
        _resource_fields_wrap = resource_fields_wrap.copy()
        for col in resource_fields_wrap:
            if col not in ['type', 'subtype']:
                _resource_fields_wrap.pop(col, None)
        #_resource_fields_detail_wrap = {}
        #resource_fields_detail[__head_detail_rates__] = \
        #       fields.List(fields.Nested(resource_fields_detail_rates))
        resource_fields_detail[__head_detail_deals__] = \
               fields.List(fields.Nested(resource_fields_detail_deals))

        _resource_fields_detail_rates = {}
        #_resource_fields_detail_rates['user'] = fields.Nested(resource_fields_detail_rates)
        _resource_fields_detail_rates = resource_fields_detail_rates.copy()
        resource_fields_detail['users'] = \
               fields.List(fields.Nested(_resource_fields_detail_rates))
        #resource_fields.update(resource_fields_detail)
        resource_fields_detail[__head_detail_images_url__] = \
                fields.Nested(resource_fields_detail_images_url)
        #resource_fields[__head_detail__] = fields.Nested(_resource_fields_detail_wrap)
        #_resource_fields_wrap[field_inputs_wrap_head] = fields.Nested(resource_fields)
        _resource_fields_wrap[field_inputs_wrap_head] = fields.Nested(
            resource_fields_detail)

        #print('_resource_fields_wrap ', resource_fields)

        _r = r
        #for col in resource_fields.keys():
        #    self.args[field_inputs_wrap_head][col] = getattr(_r, col)
        #for col in resource_fields.keys():
        for col in _r.__table__.columns.keys():
            self.args[field_inputs_wrap_head][col] = getattr(_r, col)

        self.args[field_inputs_wrap_head]['name'] = getattr(_r.meta, 'name')

        rate = 0
        self.args[field_inputs_wrap_head]['rate'] = rate
        self.args[field_inputs_wrap_head]['users'] = []
        self.args[field_inputs_wrap_head][__head_detail_deals__] = []
        self.args[field_inputs_wrap_head]['images_url'] = {}


        __r = db.session.query(rates).\
                filter(rates.business_id == id).all()
        r_len = len(__r)
        self.args[field_inputs_wrap_head]['rate_nr'] = r_len
        if r_len > 0:
            for ___r in __r:
                rate += ___r.rate
            self.args[field_inputs_wrap_head]['rate'] = int(rate / r_len)

        # FIXME: hard code
        __r = db.session.query(comment).\
                filter(comment.business_id == id).order_by(comment.mtime.desc()).offset(0).limit(5).all()
        r_len = len(__r)
        self.args[field_inputs_wrap_head]['user_nr'] = r_len
        if r_len > 0:
            for __r in __r:
                ___r = db.session.query(Users).\
                        filter(__r.user_id == Users.id).scalar()

                self.args[field_inputs_wrap_head]['users'].append(
                    #{'user':
                    {
                        'id': ___r.id,
                        'avatar_url': ___r.avatar_url
                    }
                    #}
                )

        # TODO: get favorite by User id from session

        _r = deals.query.filter(deals.business_id == id).all()
        r_len = len(_r)
        if r_len:
            for __r in _r:
                self.args[field_inputs_wrap_head][
                    __head_detail_deals__].append({
                        'title':
                        __r.title,
                        'description':
                        __r.description
                    })

        _r = pics.query.filter(pics.business_id == id).all()
        # (1, 'icon'), (2, 'bg'), (3, 'gallery')
        r_len = len(_r)
        if r_len > 0:
            # TODO: mapping table
            for __r in _r:
                if getattr(__r, 'type') == 1:
                    self.args[field_inputs_wrap_head]['images_url']['icon'] = \
                    getattr(__r, 'path')
                    r_len -= 1
                elif getattr(__r, 'type') == 2:
                    self.args[field_inputs_wrap_head]['images_url']['bg'] = \
                    getattr(__r, 'path')
                    r_len -= 1

        self.args[field_inputs_wrap_head]['gallery_nr'] = r_len
        self.args[field_inputs_wrap_head]['id'] = id

        self.args['type'] = "business"
        self.args['subtype'] = "overview"
        #print('self.args= ', self.args, '_resource_fields_wrap', _resource_fields_wrap)

        return marshal(self.args, _resource_fields_wrap), 200
Example #23
0
    def get(self):
        """Get all data, getall
        """
        # check the request is validtion,
        # ex: we not allow request arg 'itemsPerPage1'

        validSet = set(field_inputs_wrap.keys())
        requestArgsSet = set(request.dataDictWrap.keys())

        if not ExtraParamsIsValid(requestArgsSet, validSet):
            return omitError(
                ErrorMsg=repr(requestArgsSet.difference(validSet))), 400

        # one to many
        # 1. parsing reqest
        try:
            for k, v in field_inputs.items():
                field_inputs[k]['required'] = False

            orgArgs, self.args = GetRequestArgs(
                None, field_inputs_wrap,
                dict((col, request.args.get(col)) for col in request.args))
            # get default value
            # print(self.args, 'self.args', resource_fields_wrap)
            self.response = dict(
                marshal(self.args, resource_fields_wrap).items())

            self.args[field_inputs_wrap_head] = []
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError(ErrorMsg=repr(error)), 400

        itemsPerPage = self.response['itemsPerPage']
        page = self.response['page']
        orderBy = getattr(obj, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        r = obj.query.filter(obj.isdel == False).order_by(isDesc())
        _r = r.all()
        self.args['total'] = len(_r)

        if itemsPerPage is not 0:
            _r = r.offset(itemsPerPage * (page-1))\
                    .limit(itemsPerPage)\
                    .all()

        r = _r
        # 2. export to user
        for _r in r:
            __r = dict(
                (col, getattr(_r, col)) for col in _r.__table__.columns.keys())
            self.args[field_inputs_wrap_head].append(__r)

        _resource_fields = resource_fields.copy()
        _resource_fields_wrap = resource_fields_wrap.copy()
        _resource_fields_wrap[field_inputs_wrap_head] = fields.List(
            fields.Nested(_resource_fields))
        self.args['type'] = "business"
        self.args['subtype'] = "rate"
        return marshal(self.args, _resource_fields_wrap), 200
Example #24
0
    def post(self):
        """upload pics to business

        @api {post} /rest/pic/gallery upload multiple pictures to business
        @apiVersion 0.0.5
        @apiName UploadPicsToBusiness
        @apiGroup business
        @apiPermission registered user


        @apiDescription
        todo certificate with cookies / oauth 2.0<br />
        todo long/lat validation<br />
        todo metadata for counter of registerd devices<br />
        todo error / success return code in api

        @apiHeader {String}         file[]      upload file path 
        @apiHeader {Number}         business_id upload to business
        @apiHeader {String={customer}}         type      upload type
        @apiExample {curl} Example usage:
        curl -v -i -X POST -H "Content-Type: multipart/form-data" -F "file[]=@20160618_6615.jpg" -F "business_id=1" -F type="customer" -F "file[][email protected]" http://localhost/rest/pic/gallery

        {  
            "type":"pic",
            "data":[  
                {  
                    "id":9,
                    "path":"/img/customer/1/G30SLL_20160618_6615.jpg",
                    "height":1365,
                    "width":1024
                },
                {  
                    "id":10,
                    "path":"/img/customer/1/3AZGA4_10473.jpg",
                    "height":1365,
                    "width":1024
                }
            ],
            "page":1,
            "subtype":"gallery",
            "gallery_nr":2,
            "total":6
        }

        @apiSuccess {Number}   total         total items in one business 
        @apiSuccess {String}   orderBy       the items order by column you specified
        @apiSuccess {Number}   page          page you want to request from, start with 1
        @apiSuccess {Number}   gallery_nr    current upload files number
        @apiSuccess {String}   type          request's type
        @apiSuccess {String}   subtype       request's subtype

        @apiSuccess {Object[]}   data       object

        @apiSuccess {Number}     data.id    image's id
        @apiSuccess {Number}     data.path  image's url that you could directly access
        @apiSuccess {Number}     data.height image's height(px)
        @apiSuccess {Number}     data.width image's width(px)
        """

        try:
            orgArgs, self.args = GetTwoLayerRequestArgs(
                None, field_inputs, request.form)
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

            return omitError('CE_INVALID_PARAM', 'not found'), 400

        id = self.args['business_id']
        type = self.args['type']
        #print(self.args, 'self.args', id, type)
        #self.args = {}
        #id = request.form.get('business_id')
        #type = request.form.get('type')

        #if type not in PIC_ALLOWED_TYPE:
        #    logger.debug('%s not in PIC_ALLOWED_TYPE', type)
        #    type = None

        #if not id or not type:
        #    return omitError('CE_INVALID_PARAM', 'id {} not found'.format(id)), 400

        print("galleryed_files", request.files, "form data=", request.form)

        # 1. check id exist
        r = business.query.filter(business.id == id,
                                  business.isdel == False).scalar()

        if r is None:
            return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400

        # if dir not exist, create it
        # /img/business/1/
        pic_dir = os.path.join(STATIC_ROOT, PIC_PREFIX, type, str(id))
        rest_pic_prefix = os.path.join(REST_PIC_PREFIX, type, str(id))

        if not os.path.exists(pic_dir):
            os.makedirs(pic_dir)

        # TODO: review trigger time
        # 2. check last status that records are same with local
        _pics = []
        count = 0
        filenames = next(os.walk(pic_dir))[2]
        _filenames = filenames.copy()
        print("filenames=", _filenames)
        ps = obj.query.filter(obj.business_id == id).all()
        for v in ps:
            #print("filenames=", filenames, "v.path=", v.path)
            if v.path in filenames:
                count += 1
                _filenames.remove(v.path)
            else:
                # prepare remove
                _pics.append(v)

        # TODO: need check duplicate record?
        # 2.1. commit to delete not relationship records
        try:
            for v in _pics:
                db.session.delete(v)

            db.session.flush()
            db.session.commit()
        except Exception as error:
            db.session.rollback()
            logger.warning('session commit error(%s)', error)

            return omitError(ErrorMsg=repr(error)), 400

        # remove not exist db's file
        for v in _filenames:
            os.remove(os.path.join(pic_dir, v))

        # 3. validate follows spec
        if count > max:
            return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400

        # 4. check pic name
        _pics = []
        filenames = []
        galleryed_files = request.files.getlist("file[]")
        print("galleryed_files file[]= ", galleryed_files)

        if len(galleryed_files) == 0:
            galleryed_files = request.files.getlist("customer")  # for ios
            print("galleryed_files customer= ", galleryed_files)

        for file in galleryed_files:
            # Check if the file is one of the allowed types/extensions
            if file and self.allowed_file(file.filename):
                # Make the filename safe, remove unsupported chars
                filename = secure_filename(file.filename)
                print("file.filename=", file.filename, "filename=", filename)
                # Move the file form the temporal folder to the gallery
                # folder we setup
                p = obj()
                rs = ''.join(
                    random.SystemRandom().choice(string.ascii_uppercase +
                                                 string.digits)
                    for _ in range(6))
                # 5FATMM_35e4183b.jpg.png -> 5FATMM_35e4183b.png
                extend = os.path.splitext(filename)[1]
                #print("self.remove_extend(filename)=", self.remove_extend(filename))
                p.path = '_'.join([rs, self.remove_extend(filename)]) + extend
                p.business_id = id
                # (1, 'icon'), (2, 'bg'), (3, 'gallery')
                p.type = 3

                _pics.append(p)
                filenames.append(filename)

        # 4. move to pic dir
        # FIXME: check file exist if abnormal error that db record save but pic not exist
        self.args[field_inputs_wrap_head] = []
        path = []
        _filenames = []
        for k, v in enumerate(_pics):
            filename = os.path.join(pic_dir, filenames[k])
            n_filename = os.path.join(pic_dir, v.path)

            try:
                # FIXME: handle <FileStorage: '35e4183b.jpg.png' ('application/octet-stream')>)
                galleryed_files[k].save(filename)
                #import shutil
                #shutil.copy(filename, n_filename)
                os.rename(filename, n_filename)
                _filenames.append(n_filename)

                print("n_filename = ", n_filename, "filename=", filename)
                img = Image.open(n_filename)
                s = img.size
                ratio = 0
                v.width = s[0]
                v.height = s[1]
                if s[0] > MAXWIDTH:
                    ratio = MAXWIDTH / s[0]
                    v.width = MAXWIDTH
                    v.height = int(round(s[1] * ratio))
                    img.thumbnail((v.width, v.height), Image.ANTIALIAS)
                print("img = ", img, "n_filenam=", n_filename, "format:",
                      img.format, "width:", MAXWIDTH, ", height: ",
                      int(round(s[1] * ratio)), "orgsize:", s)
                #img.save(n_filename, img.format)
                # FIXME: open 35e4183b.jpg.png error
                img.save(n_filename)

            except IOError:
                #for v in _filenames:
                #    os.remove(v)

                return omitError('CE_IMAGE_RESIZE',
                                 'image resize {} error'.format(
                                     filenames[k])), 400

        # 5. commit to save
        try:
            for v in _pics:
                db.session.add(v)

            db.session.flush()
            db.session.refresh(r)

            for v in _pics:
                _pic = dict((col, getattr(v, col))
                            for col in v.__table__.columns.keys())
                print("_pic:", _pic)
                _pic['path'] = os.path.join(rest_pic_prefix, v.path)
                self.args[field_inputs_wrap_head].append(_pic)

            db.session.commit()
        except Exception as error:
            db.session.rollback()
            logger.warning('session commit error(%s)', error)

            return omitError(ErrorMsg=repr(error)), 400

        #output = {"type": "pic", "subtype": "gallery",
        #        "imgs": {"total": count, "gallery_nr": len(_pics), "path": (path)}}

        for v in ['itemsPerPage', 'desc', 'orderBy']:
            resource_fields_wrap.pop(v, None)

        _resource_fields = {}
        resource_fields_wrap[field_inputs_wrap_head] = fields.List(
            fields.Nested(resource_fields_post))

        self.args['total'] = len(
            obj.query.filter(obj.business_id == id, obj.isdel == False).all())
        self.args['gallery_nr'] = len(_pics)
        self.args['type'] = "pic"
        self.args['subtype'] = "gallery"
        return marshal(self.args, resource_fields_wrap), 200