Ejemplo n.º 1
0
    def delete(self):
        """multi delete
        """
        try:
            ids = request.args.get(__heads__).split(',')
        except Exception as error:
            return omitError(
                ErrorMsg='param `{}` not found'.format(__heads__)), 400

        for id in ids:
            try:
                id = inputs.natural(id)
            except Exception as error:
                db.session.rollback()
                return omitError(
                    ErrorMsg='user id `{}` not int'.format(id)), 400

            # it could als cascade delete `online` user
            r = grp.query.filter(grp.id == id).scalar()
            if r is None:
                db.session.rollback()
                return omitError('CE_NOT_EXIST',
                                 'id {} not found'.format(id)), 400

            db.session.delete(r)

        try:
            db.session.flush()
            db.session.commit()
        except Exception as error:
            logger.warning('session commit error(%s)', error)
            db.session.rollback()
            return omitError(ErrorMsg=repr(error)), 400

        return '', 204
Ejemplo n.º 2
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
Ejemplo n.º 3
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
Ejemplo n.º 4
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
Ejemplo n.º 5
0
    def put(self, id):
        """ update one item
        """
        # 1. parsing reqest
        try:
            orgArgs, self.args = GetTwoLayerRequestArgs(
                field_inputs_wrap_head, field_inputs_post)

        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 = 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

        # 3. assign request data to orm
        try:
            t = datetime.utcnow()
            r = PrepareObjORM(r, self.args.items())
            r.mtime = t

        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
        out = SerialObjOutput(r,
                              objname=field_inputs_wrap_head,
                              resource_fields=resource_fields_post), 200

        next(iter(out))[field_inputs_wrap_head].update({'id': id})
        next(iter(out))['type'] = 'business'
        next(iter(out))['subtype'] = 'rate'

        return out
Ejemplo n.º 6
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
Ejemplo n.º 7
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 :(')

            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[__sec_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(sec, self.response['orderBy'])
        isDesc = getattr(orderBy, 'desc' if self.response['desc'] else 'asc')

        r = sec.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[__sec_heads__] = data

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

        return marshal(self.args, _resource_fields_wrap), 200
Ejemplo n.º 8
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
Ejemplo n.º 9
0
def checkInputIsValid(args={}):
    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())
        raise ValueError(
            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())
        raise ValueError( omitError('CE_INVALID_PARAM', '`{}/{}({})`: {}'.\
                format(ip, pre, ver, error.args)), 400)
Ejemplo n.º 10
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
Ejemplo n.º 11
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
Ejemplo n.º 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
Ejemplo n.º 13
0
    def delete(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:
            ids = request.args.get(__heads__).split(',')
        except Exception as error:
            return omitError(
                ErrorMsg='param `{}` not found'.format(__heads__)), 400

        for id in ids:
            try:
                id = inputs.natural(id)
            except Exception as error:
                db.session.rollback()
                return omitError(
                    ErrorMsg='user id `{}` not int'.format(id)), 400

            # it could als cascade delete `online` user
            r = obj.query.filter(obj.id == id).scalar()
            if r is None:
                db.session.rollback()
                return omitError('CE_NOT_EXIST',
                                 'admin id {} not found'.format(id)), 400

            db.session.delete(r)

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

        return message, 204
Ejemplo n.º 14
0
    def delete(self):
        """multi delete
        """
        try:
            ids = request.args.get(__heads__).split(',')
        except Exception as error:
            return omitError(
                ErrorMsg='param `{}` not found'.format(__heads__)), 400

        # TODO: use function
        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

        if r.login != superuser:
            return omitError('CE_UNAUTHORIZED', 'permission deny'), 400

        for id in ids:
            try:
                id = inputs.natural(id)
            except Exception as error:
                return omitError(ErrorMsg='id `{}` not int'.format(id)), 400

            # it could als cascade delete `online` user
            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

        _r = []
        for id in ids:
            id = inputs.natural(id)

            # it could als cascade delete `online` user
            r = obj.query.filter(obj.id == id, obj.isdel == False).scalar()
            r.isdel = True
            _r.append(r)

        try:
            for v in _r:
                db.session.merge(v)

            db.session.flush()
            db.session.commit()
        except Exception as error:
            logger.warning('session commit error(%s)', error)
            db.session.rollback()
            return omitError(ErrorMsg=repr(error)), 400

        return '', 204
Ejemplo n.º 15
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
Ejemplo n.º 16
0
    def put(self, id):
        """
            update one item

        @api {put} /rest/customer/business/:id Update a item
        @apiVersion 0.0.5
        @apiName UpdateCustomerBusiness
        @apiGroup business
        @apiPermission registered user


        @apiDescription
        todo certificate with cookies / oauth 2.0<br />
        todo long/lat validation<br />
        todo error / success return code in api <br />

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


        @apiExample {curl} Example usage:
        curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "
        {  
            "data":{  
                "dist":12245,
                "close":"2200",
                "lat":120.678,
                "features":"this is features",
                "address":"this is address",
                "deals":[  
                    {  
                        "title":"10% Off Any Order",
                        "description":"Use this promo code and save on coffee, tea, and..."
                    }
                ],
                "cat":1,
                "long":23.5383,
                "meals":"this is meals",
                "deal":200,
                "open":"0600",
                "description":"early Bird Special: Get  off.",
                "name":"Starbucks Coffee 31",
                "images_url":{  
                    "icon":"/img/business/1/icon",
                    "bg":"/img/business/1/bg"
                },
                "id":1
            },
            "type":"business",
            "subtype":"overview"
        }
        " http://localhost/rest/customer/business/1

        @apiError CE_INVALID_PARAM invalid parameter

           HTTP/1.0 400 BAD REQUEST
           {
               "errorId": 2001,
               "message": "ValueError('[cat]: (cat Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)"
           }

        @apiError CE_NAME_CONFLICT name conflict
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2004,
            "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: customer_businesses.name',)"
        }

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

        """
        # 1. parsing reqest
        try:
            orgArgs, self.args = GetTwoLayerRequestArgs(
                field_inputs_wrap_head, field_inputs_post)
            RemoveRequestArgs(field_inputs_post)
            j = request.get_json()
            orgdetailImgsUrlArgs, self.detailimgsurlargs = GetTwoLayerRequestArgs(
                None, field_inputs_detail_images_url,
                j[field_inputs_wrap_head][__head_detail_images_url__])

        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 = 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

        # 3. assign request data to orm
        try:
            t = datetime.utcnow()

            _item = []
            for k, v in self.args.items():
                if k != "deals":
                    _item.append((k, v))
            r = PrepareObjORM(r, _item)

            r.mtime = t

            d = detail.query.filter(detail.business_id == id,
                                    detail.isdel == False).scalar()
            __deals = deals.query.filter(deals.business_id == id,
                                         deals.isdel == False).all()
            # TODO: mark isdel = True?
            #for v in __deals:
            #    v.isdel = True;

            _deals = []
            for k, v in self.args.items():
                if v != None:
                    if k == 'deals':
                        deal = deals()
                        for v1 in v:  # each entry
                            for k2, v2 in v1.items():
                                setattr(deal, k2, v2)
                        _deals.append(deal)
                    else:
                        setattr(d, k, v)

            d.mtime = t

            _pics = []
            _ps = pics.query.filter(pics.business_id == id,
                                    pics.isdel == False).all()
            # FIXME: hard code mapping
            for k, v in self.detailimgsurlargs.items():
                # (1, 'icon'), (2, 'bg'), (3, 'gallery')
                p = pics()
                if k == 'icon':
                    p.type = 1
                elif k == 'bg':
                    p.type = 2

                if p.type:
                    p.path = v
                    _pics.append(p)

        except Exception as error:
            return omitError(ErrorMsg=repr(error)), 400

        # 4. commit to save
        try:
            #db.session.merge(r)
            for v in __deals:
                db.session.delete(v)

            for v in _ps:
                db.session.delete(v)

            for v in _pics:
                db.session.add(v)

            for v in _deals:
                db.session.add(v)

            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
        out = SerialObjOutput(d,
                              objname=field_inputs_wrap_head,
                              resource_fields=resource_fields_post), 200

        for k, v in field_inputs.items():
            if k not in ['id', 'image_url']:
                next(iter(out))[field_inputs_wrap_head].update({k: orgArgs[k]})

        next(iter(out))[field_inputs_wrap_head].update(
            {'deals': orgArgs['deals']})
        next(iter(out))[field_inputs_wrap_head].update(
            {'images_url': orgArgs['images_url']})
        next(iter(out))[field_inputs_wrap_head].update({'id': id})
        next(iter(out))['type'] = 'business'
        next(iter(out))['subtype'] = 'overview'

        return out
Ejemplo n.º 17
0
    def delete(self):
        """multi delete
        @api {delete} /rest/customer/businesses Delete items
        @apiName DelCustomerBusiness
        @apiVersion 0.0.3
        @apiGroup customer
        @apiPermission registered user

        @apiDescription
        todo validation

        @apiParam {String{..254}} [ids] the items id seperate with common

        @apiExample {curl} Example usage:
        curl -X DELETE -v -b $COOKIES -H "Content-Type:application/json" http://localhost/rest/customer/businesses?id=1,2,3
        HTTP/1.0 204 NO CONTENT


        @apiError CE_INVALID_PARAM invalid parameter
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2001,
            "message": "param `businesses` not found"
        }

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


        """
        try:
            ids = request.args.get(__heads__).split(',')
        except Exception as error:
            return omitError(
                ErrorMsg='param `{}` not found'.format(__heads__)), 400

        for id in ids:
            try:
                id = inputs.natural(id)
            except Exception as error:
                return omitError(ErrorMsg='id `{}` not int'.format(id)), 400

            # it could als cascade delete `online` user
            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

        _details = []
        _pics = []
        _deals = []
        _r = []
        for id in ids:
            id = inputs.natural(id)

            # it could als cascade delete `online` user
            r = obj.query.filter(obj.id == id, obj.isdel == False).scalar()
            r.isdel = True
            _r.append(r)

            # must have
            d = detail.query.filter(detail.business_id == id,
                                    detail.isdel == False).scalar()
            d.isdel = True
            _details.append(d)

            p = pics.query.filter(pics.business_id == id,
                                  pics.isdel == False).all()
            _pics += p

            __deals = deals.query.filter(deals.business_id == id,
                                         deals.isdel == False).all()
            _deals += __deals

        try:
            for v in _deals:
                db.session.delete(v)

            for v in _pics:
                db.session.delete(v)

            for v in _r:
                db.session.merge(v)

            for v in _details:
                db.session.merge(v)

            db.session.flush()
            db.session.commit()
        except Exception as error:
            logger.warning('session commit error(%s)', error)
            db.session.rollback()
            return omitError(ErrorMsg=repr(error)), 400

        return '', 204
Ejemplo n.º 18
0
    def put(self, id):
        """
            update one record

        @api {put} /rest/objects/ipaddr/:id update a IP Address item
        @apiVersion 0.0.1
        @apiName UpdateIpAddr
        @apiVersion 0.0.1
        @apiGroup objects
        @apiPermission registered user

        @apiParam {Number} id ipdate IP Address ID.
        
        @apiDescription
        todo validation<br />
        todo certificate with cookies / oauth 2.0

        @apiParam {Object}   ipaddrs       List of IP Addresses.
        @apiParam {String{..16}}   ipaddrs.addr1 1st IP Address.
        @apiParam {String{..16}}   ipaddrs.addr2 2ed IP Address.
        @apiParam {String{..255}}   [ipaddrs.description] this items's description.
        @apiParam {String="IPv4","IPv6"}   ipaddrs.ipVersion IP Address version.
        @apiParam {String{..50}}   ipaddrs.name items uniq name for record.
        @apiParam {String="Single","Range","Subnet"}   ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'.
        @apiExample Example usage:
           BODY=$(cat <<'EOF'
             {
               "ipaddr" : {
               "name" : "test-ipaddr-${i}8",
               "type" : "Single",
               "ipVersion" : "IPv4",
               "addr1" : "1.1.1.1",
               "description" : "xxx"
             }
           }
           EOF
           );
             
        curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" 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 {put} /rest/objects/ipaddr/:id
        @apiErrorExample {json} we use invalid member type1 in request body
           BODY=$(cat <<'EOF'
             {
               "ipaddr" : {
               "name" : "test-ipaddr-${i}8",
               "type1" : "Single",
               "ipVersion" : "IPv4",
               "addr1" : "1.1.1.1",
               "description" : "xxx"
             }
           }
           EOF
           );
             
           curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/7
           ================================================
           HTTP/1.0 400 BAD REQUEST
           {
               "errorId": 2001,
               "message": "ValueError('[type]: (type Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)"
           }

        @apiError CE_NAME_CONFLICT name conflict
        @api {post} /rest/objects/ipaddr/:id 
        @apiErrorExample {json} we use duplicate name.
            BODY=$(cat <<'EOF'
             {
               "ipaddr" : {
               "name" : "test-ipaddr-${i}8",
               "type" : "Single",
               "ipVersion" : "IPv4",
               "addr1" : "1.1.1.1",
               "description" : "xxx"
             }
           }
           EOF
           );
             
           curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/7
           ================================================
           HTTP/1.0 400 BAD REQUEST
           {
               "errorId": 2004,
               "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: objects_ipaddrs.name',)"
           }

        @apiError CE_NOT_EXIST item not found
        @api {get} /rest/objects/ipaddr/:id
        @apiErrorExample {json} we use not exist id
           curl -X PUT -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"
           }

        """
        # 1. parsing reqest
        try:
            orgArgs, self.args = GetRequestArgs(__head__, field_inputs)
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

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

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

        # 2. get orm from db
        r = obj.query.filter(obj.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 = PrepareObjORM(r, 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
        return SerialObjOutput(r,
                               objname=__head__,
                               resource_fields=resource_fields), 200
Ejemplo n.º 19
0
    def post(self):
        """create data
        """

        # 1. parsing reqest
        # 1.1 parsing 1st layer reqest

        try:
            orgArgs, self.args = GetTwoLayerRequestArgs(
                field_inputs_wrap_head, field_inputs_post)

        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

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

        # 1.3 check name unique
        r = obj.query.filter(obj.user_id == self.args['user_id'],
                             obj.business_id == self.args['business_id'],
                             obj.isdel == False).scalar()

        if r is not None:
            return omitError(
                'CE_DATA_DUPLICATE',
                'user_id {}, business_id {} are duplicate'.format(
                    self.args['user_id'], self.args['business_id'])), 400

        # 2. validate follows spec
        if db.session.query(obj).filter(obj.isdel == False).count() > max:
            return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400

        r = obj()
        try:
            r = PrepareObjORM(r, 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.refresh(r)
            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
        out = SerialObjOutput(r,
                              objname=field_inputs_wrap_head,
                              resource_fields=resource_fields_post), 200

        next(iter(out))[field_inputs_wrap_head].update({'id': r.id})
        next(iter(out))['type'] = 'business'
        next(iter(out))['subtype'] = 'rate'

        return out
Ejemplo n.º 20
0
    def post(self):
        """create data

        @api {post} /rest/customer/businesses Create a item
        @apiVersion 0.0.3
        @apiName CreateCustomerBusiness
        @apiGroup business
        @apiPermission registered user

        @apiDescription
        todo validation <br/>
        todo certificate with cookies / oauth 2.0 <br/>
        todo muti-create <br />
        todo error / success return code in api


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


        @apiExample {curl} Example usage:

        curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d '
        {  
            "data":{  
                "dist":12245,
                "close":"2200",
                "lat":120.678,
                "features":"this is features",
                "address":"this is address",
                "deals":[  
                    {  
                        "title":"10% Off Any Order",
                        "description":"Use this promo code and save on coffee, tea, and..."
                    }
                ],
                "cat":1,
                "long":23.5383,
                "meals":"this is meals",
                "deal":200,
                "open":"0600",
                "description":"early Bird Special: Get  off.",
                "name":"Starbucks Coffee 31",
                "images_url":{  
                    "icon":"/img/business/1/icon",
                    "bg":"/img/business/1/bg"
                },
                "id":1
            },
            "type":"business",
            "subtype":"overview"
        }' http://localhost/rest/customer/businesses


        @apiError CE_INVALID_PARAM invalid parameter
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2001,
            "message": "ValueError('[cat]: (cat Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)"
        }

        @apiError CE_NAME_CONFLICT name conflict
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2004,
            "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: customer_businesses.name',)"
        }


        @apiError CE_EXCEED_LIMIT exceed max limit
        HTTP/1.0 400 BAD REQUEST
        {
            "errorId": 2005,
            "message": "limit is 5"
        }

        """

        # 1. parsing reqest
        # 1.1 parsing 1st layer reqest

        try:
            #orgArgs = {'type': 'business', 'subtype': 'overview', 'data': {'name': 'Starbucks Coffee 1', 'description': 'early Bird Special: Get  off.', 'address': 'this is address', 'close': '2200', 'meals': 'this is meals', 'long': 23.5383, 'open': '0600', 'lat': 120.678, 'dist': 12245, 'cat': 1, 'images_url': {'icon': '/img/business/1/icon', 'bg': '/img/business/1/bg'}, 'features': 'this is features', 'deal': 200, 'deals': [{'description': 'Use this promo code and save on coffee, tea, and...', 'title': '10% Off Any Order'}]}}'

            orgArgs, self.args = GetTwoLayerRequestArgs(
                field_inputs_wrap_head, field_inputs_post)
            RemoveRequestArgs(field_inputs_post)
            j = request.get_json()
            orgdetailImgsUrlArgs, self.detailimgsurlargs = GetTwoLayerRequestArgs(
                None, field_inputs_detail_images_url,
                j[field_inputs_wrap_head][__head_detail_images_url__])
            #self.args= {'name': 'Starbucks Coffee 1', 'description': 'early Bird Special: Get  off.', 'address': 'this is address', 'close': '2200', 'meals': 'this is meals', 'long': '23.5383', 'open': '0600', 'lat': '120.678', 'dist': 12245, 'cat': 1, 'features': 'this is features', 'deal': 200, 'deals': [{'description': 'Use this promo code and save on coffee, tea, and...', 'title': '10% Off Any Order'}]} self.detailimgsurlargs= {'icon': '/img/business/1/icon', 'bg': '/img/business/1/bg'}}
            #print("self.args=", self.args, "self.detailimgsurlargs=", self.detailimgsurlargs)

        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

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

        # 1.3 check name unique
        r = obj.query.filter(obj.name == self.args['name'],
                             obj.isdel == False).scalar()

        if r is not None:
            return omitError('CE_NAME_CONFLICT',
                             'name {} conflict'.format(self.args['name'])), 400

        # 2. validate follows spec
        if db.session.query(obj).filter(obj.isdel == False).count() > max:
            return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400

        r = obj()
        d = detail()
        _pics = []
        _deals = []
        try:
            _item = []
            for k, v in self.args.items():
                if k != "deals":
                    _item.append((k, v))
            r = PrepareObjORM(r, _item)

            # FIXME: hard code mapping
            for k, v in self.detailimgsurlargs.items():
                # (1, 'icon'), (2, 'bg'), (3, 'gallery')
                p = pics()
                if k == 'icon':
                    p.type = 1
                elif k == 'bg':
                    p.type = 2

                if p.type:
                    p.path = v
                    _pics.append(p)

            for k, v in self.args.items():
                if v != None:
                    if k == 'deals':
                        deal = deals()
                        for v1 in v:  # each entry
                            for k2, v2 in v1.items():
                                setattr(deal, k2, v2)
                        _deals.append(deal)
                    else:
                        setattr(d, k, v)
            #print("d.__dict__ = ", d.__dict__)

        except Exception as error:
            return omitError(ErrorMsg=repr(error)), 400

        # 4. commit to save
        try:
            db.session.add(r)
            # At this point, the object f has been pushed to the DB,
            # and has been automatically assigned a unique primary key id
            db.session.flush()
            # refresh updates given object in the session with its state in the DB
            # (and can also only refresh certain attributes - search for documentation)
            db.session.refresh(r)

            d.business_id = r.id
            #print("d.__dict__ = ", d.__dict__)
            db.session.add(d)
            for v in _deals:
                v.business_id = r.id
                db.session.add(v)

            for v in _pics:
                v.business_id = r.id
                db.session.add(v)

            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
        _d = db.session.query(detail).filter(detail.business_id == r.id).one()
        out = SerialObjOutput(_d,
                              objname=field_inputs_wrap_head,
                              resource_fields=resource_fields_post), 200

        for k, v in field_inputs.items():
            if k not in ['id', 'image_url']:
                next(iter(out))[field_inputs_wrap_head].update({k: orgArgs[k]})

        next(iter(out))[field_inputs_wrap_head].update(
            {'deals': orgArgs['deals']})
        next(iter(out))[field_inputs_wrap_head].update(
            {'images_url': orgArgs['images_url']})
        next(iter(out))[field_inputs_wrap_head].update({'id': r.id})
        next(iter(out))['type'] = 'business'
        next(iter(out))['subtype'] = 'overview'

        return out
Ejemplo n.º 21
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
Ejemplo n.º 22
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
Ejemplo n.º 23
0
    def put(self, id):
        """ update one item
        """
        """update comment 

        @api {put} /rest/customer/comment/:id create comment
        @apiVersion 0.0.5
        @apiName UpdateComment
        @apiGroup campaign
        @apiPermission registered user
        @apiParam {Number} id comment id

        @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 {Object}          data        object
        @apiParam {String{..254}}   data.content message's title
        @apiParam {Number}          data.business_id comment belong to the business_id 
        @apiParam {Number}          data.user_id  user who create it
        @apiParam {Number={0..5}}   data.rate    comment's rate
        @apiParam {String}          type         request's type
        @apiParam {String}          subtype      request's subtype
        @apiExample {curl} Example usage:

        curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "
        {  
            "subtype":"comment",
            "type":"business",
            "data":{  
                "content":"Starbucks were all over Singapore and the quality ",
                "business_id":1,
                "user_id":2,
                "rate":1
            }
        }" http://localhost/rest/customer/comment/1

        HTTP/1.0 200 OK
        {  
            "data":{  
                "content":"Starbucks were all over Singapore and the quality ",
                "user_id":1,
                "business_id":1,
                "rate":1,
                "mtime":"2016-08-31 04:16:42.091706",
                "id":2
            },
            "type":"business",
            "subtype":"comment"
        }

        @apiSuccess {Object}          data        object
        @apiSuccess {String{..254}}   data.content message's title
        @apiSuccess {Number}          data.business_id comment belong to the business_id 
        @apiSuccess {Number}          data.user_id  user who create it
        @apiSuccess {Number}          data.id      comment's id
        @apiSuccess {String{..254}}   data.mtime   comment's modify time
        @apiSuccess {Number={0..5}}   data.rate    comment's rate
        @apiSuccess {String}          type         request's type
        @apiSuccess {String}          subtype      request's subtype
        """

        # 1. parsing reqest
        try:
            orgArgs, self.args = GetTwoLayerRequestArgs(
                field_inputs_wrap_head, field_inputs_post)

        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 = 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

        # 3. assign request data to orm
        try:
            t = datetime.utcnow()
            r = PrepareObjORM(r, self.args.items())
            r.mtime = t

        except Exception as error:
            return omitError(ErrorMsg=repr(error)), 400

        # TODO: make sure tranaction
        _r = rates.query.filter(rates.user_id == self.args['user_id'],
                                rates.business_id == self.args['business_id'],
                                rates.isdel == False).scalar()

        if _r is None:
            return omitError(
                'CE_NOT_EXIST', 'user_id {}, business_id {} '.format(
                    self.args['user_id'], self.args['business_id'])), 400

        _r.rate = self.args['rate']

        # 4. commit to save
        try:
            db.session.merge(r)
            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
        out = SerialObjOutput(r,
                              objname=field_inputs_wrap_head,
                              resource_fields=resource_fields_post), 200

        next(iter(out))[field_inputs_wrap_head].update({'id': id})
        next(iter(out))[field_inputs_wrap_head].update(
            {'rate': self.args['rate']})
        next(iter(out))['type'] = 'business'
        next(iter(out))['subtype'] = 'comment'

        return out
Ejemplo n.º 24
0
    def put(self, id):
        """ update one item
        """
        # 1. parsing reqest
        try:
            orgArgs, self.args = GetTwoLayerRequestArgs(
                field_inputs_wrap_head, field_inputs_post)

        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 = 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

        # 3. assign request data to orm
        try:
            t = datetime.utcnow()
            if not self.args['passHash']:
                self.args['passHash'] = r.passHash

            # not allow others change expect itself
            # TODO: raise custome error
            check_permission(self.args['login'], r.login)

            # not allow change login name
            self.args['login'] = r.login

            r = PrepareObjORM(r, self.args.items())
            r.mtime = t

        except Exception as error:
            if RuntimeError == type(error):
                return omitError('CE_UNAUTHORIZED', repr(error)), 400

            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
        _resource_fields_post = resource_fields_post.copy()
        _resource_fields_post.pop('access_token', None)
        out = SerialObjOutput(r,
                              objname=field_inputs_wrap_head,
                              resource_fields=_resource_fields_post), 200

        next(iter(out))['type'] = 'system'
        next(iter(out))['subtype'] = 'regist'

        return out
Ejemplo n.º 25
0
    def post(self):
        """regist local user

        @api {post} /rest/admins regist local account
        @apiVersion 0.0.5
        @apiName RegistOneUser
        @apiGroup account
        @apiPermission registered user

        @apiDescription
        todo certificate with cookies / oauth 2.0<br />
        todo validation<br />
        todo error / success return code in api

        @apiParam {Object[]}        user         user object
        @apiParam {String{..254}}   user.name    user name for display
        @apiParam {String{..254}}   user.login   user email for login
        @apiParam {String{..254}}   user.passHash user password encode with sha1
        @apiExample {curl} Example usage:

        curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "
        {  
            'data':{  
                'id':2,
                'login':'******',
                'passHash':'c4f9375f9834b4e7f0a528cc65c055702bf5f24a',
                'name':'test'
            },
            'type':'system',
            'subtype':'regist'
        }
        " http://localhost/rest/admins
        """

        # 1. check id exist
        try:
            orgArgs, self.args = GetTwoLayerRequestArgs(
                field_inputs_wrap_head, field_inputs_post)
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

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

        # 2. validate follows spec
        if db.session.query(obj).filter(obj.isdel == False).count() > max:
            return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400

        # 3 check name unique
        r = obj.query.filter(obj.login == self.args['login'],
                             obj.isdel == False).scalar()

        if r is not None:
            return omitError(
                'CE_DATA_DUPLICATE',
                'login {} is duplicate'.format(self.args['login'])), 400

        r = obj()
        try:
            r = PrepareObjORM(r, 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.refresh(r)
            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
        _resource_fields_post = resource_fields_post.copy()
        _resource_fields_post.pop('access_token', None)
        out = SerialObjOutput(r,
                              objname=field_inputs_wrap_head,
                              resource_fields=_resource_fields_post), 200

        next(iter(out))[field_inputs_wrap_head].update({'id': r.id})
        next(iter(out))['type'] = 'system'
        next(iter(out))['subtype'] = 'regist'

        return out
Ejemplo n.º 26
0
    def post(self):
        """create data

         @api {post} /rest/objects/ipaddrs Create a IP Address item
         @apiVersion 0.0.1
         @apiName CreateIpAddr
         @apiVersion 0.0.1
         @apiGroup objects
         @apiPermission registered user
         
         @apiDescription
         todo validation <br/>
         todo certificate with cookies / oauth 2.0 <br/>
         todo muti-create

         @apiParam {Object}   ipaddrs       List of IP Addresses.
         @apiParam {String{..16}}   ipaddrs.addr1 1st IP Address.
         @apiParam {String{..16}}   ipaddrs.addr2 2ed IP Address.
         @apiParam {String{..255}}   [ipaddrs.description] this items's description.
         @apiParam {String="IPv4","IPv6"}   ipaddrs.ipVersion IP Address version.
         @apiParam {String{..50}}   ipaddrs.name items uniq name for record.
         @apiParam {String="Single","Range","Subnet"}   ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'.
         @apiExample Example usage:
            BODY=$(cat <<'EOF'
              {
                "ipaddr" : {
                "name" : "test-ipaddr-${i}8",
                "type" : "Single",
                "ipVersion" : "IPv4",
                "addr1" : "1.1.1.1",
                "description" : "xxx"
              }
            }
            EOF
            );
              
         curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs
         
         @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 {post} /rest/objects/ipaddrs 
         @apiErrorExample {json} we use invalid parameter pages
            BODY=$(cat <<'EOF'
              {
                "ipaddr" : {
                "name" : "test-ipaddr-${i}8",
                "type1" : "Single",
                "ipVersion" : "IPv4",
                "addr1" : "1.1.1.1",
                "description" : "xxx"
              }
            }
            EOF
            );
              
            curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs
            ================================================
            HTTP/1.0 400 BAD REQUEST
            {
                "errorId": 2001,
                "message": "ValueError('[type]: (type Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)"
            }

         @apiError CE_NAME_CONFLICT name conflict
         @api {post} /rest/objects/ipaddrs 
         @apiErrorExample {json} we use duplicate name.
             BODY=$(cat <<'EOF'
              {
                "ipaddr" : {
                "name" : "test-ipaddr-${i}8",
                "type" : "Single",
                "ipVersion" : "IPv4",
                "addr1" : "1.1.1.1",
                "description" : "xxx"
              }
            }
            EOF
            );
              
            curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs
            ================================================
            HTTP/1.0 400 BAD REQUEST
            {
                "errorId": 2004,
                "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: objects_ipaddrs.name',)"
            }

         @apiError CE_EXCEED_LIMIT exceed max limit
         @api {post} /rest/objects/ipaddrs 
         @apiErrorExample {json} we create item exceed max.
            BODY=$(cat <<'EOF'
              {
                "ipaddr" : {
                "name" : "test-ipaddr-${i}8",
                "type" : "Single",
                "ipVersion" : "IPv4",
                "addr1" : "1.1.1.1",
                "description" : "xxx"
              }
            }
            EOF
            );
              
            curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs
            ================================================
            HTTP/1.0 400 BAD REQUEST
            {
                "errorId": 2005,
                "message": "limit is 5"
            }

        """

        # 1. parsing reqest
        # 1.1 parsing 1st layer reqest
        try:
            orgArgs, self.args = GetRequestArgs(__head__, field_inputs)
        except Exception as error:
            logger.debug('traceback.format_exc(%s)', traceback.format_exc())

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

        # 1.2 parsing 2ed layer reqest
        try:
            for v in set((v) for v in set(field_inputs).intersection(orgArgs)
                         if isinstance(field_inputs[v]['validator'], set)):
                _type = field_inputs[v]['validator']

                validator = next(iter(_type)).container.nested.items() \
                      if type(_type) is set else _type.items()

                # validate 2ed value
                # if is list, such as [{id: 1, name:2}, {id: 2, name:2}]
                for _k, _v in validator:
                    for __v in orgArgs[v]:
                        if (_v.get('required', False)):
                            _v['type'](__v[_k])

                self.args[v] = self.args[v] if self.args.get(v, False) else []
                self.args[v].append(__v)

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

        logger.debug('parsed args = (%s)', self.args)

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

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

        r = obj()
        try:
            r = PrepareObjORM(r, 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
        return SerialObjOutput(r,
                               objname=__head__,
                               resource_fields=resource_fields), 200
Ejemplo n.º 27
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
Ejemplo n.º 28
0
    def delete(self):
        """multi delete
        @api {delete} /rest/objects/ipaddrs delete IP address items.
        @apiName DelIpAddrs
        @apiVersion 0.0.1
        @apiGroup objects
        @apiPermission registered user
        
        @apiDescription
        todo validation
        
        @apiParam {String{..255}} [ids] the items id seperate with common

        @apiExample Example usage:
        curl -X DELETE -v -b $COOKIES -H "Content-Type:application/json" http://localhost/rest/objects/ipaddrs?id=1,2,3
        ================================================
        HTTP/1.0 204 NO CONTENT
         

        @apiError CE_INVALID_PARAM invalid parameter
        @api {delete} /rest/objects/ipaddrs
        @apiErrorExample {json} we use invalid parameter pages
        curl -X DELETE -v -b $COOKIES -H "Content-Type:application/json" http://localhost/rest/objects/pages?id=1,2,3
        ================================================
            HTTP/1.0 400 BAD REQUEST
           {
               "errorId": 2001,
               "message": "param `ipaddrs` not found"
           }
        
        @apiError CE_NOT_EXIST item not found
        @api {delete} /rest/objects/ipaddr
        @apiErrorExample {json} we use not exist id
        curl -X DELETE -v -b $COOKIES -H "Content-Type:application/json" http://localhost/rest/objects/pages?id=7,8,9
        ================================================
            HTTP/1.0 400 BAD REQUEST
           {
               "errorId": 2003,
               "message": "id 7 not found"
           }


        """
        try:
            ids = request.args.get(__heads__).split(',')
        except Exception as error:
            return omitError(
                ErrorMsg='param `{}` not found'.format(__heads__)), 400

        for id in ids:
            try:
                id = inputs.natural(id)
            except Exception as error:
                db.session.rollback()
                return omitError(ErrorMsg='id `{}` not int'.format(id)), 400

            # it could als cascade delete `online` user
            r = obj.query.filter(obj.id == id).scalar()
            if r is None:
                db.session.rollback()
                return omitError('CE_NOT_EXIST',
                                 'id {} not found'.format(id)), 400

            db.session.delete(r)

        try:
            db.session.flush()
            db.session.commit()
        except Exception as error:
            logger.warning('session commit error(%s)', error)
            db.session.rollback()
            return omitError(ErrorMsg=repr(error)), 400

        return '', 204
Ejemplo n.º 29
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
Ejemplo n.º 30
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