Ejemplo n.º 1
0
    def test_upload_item_images_post_uuid_failed(self):
        """
        Test posting images for an item via uuid with invalid image fails.
        """
        self._create_item_status()
        item = Item(name='iPhone',
                    type='TRADE',
                    quantity=1,
                    description='A smart phone',
                    status=self.draft_status,
                    reason='just because')
        DBSession.add(item)
        DBSession.commit()

        class DumbMockImage(object):
            file = StringIO('image')
            filename = 'image1.jpg'

        item_uuid = str(uuid.uuid4())
        mock_image = DumbMockImage()

        payload = {"uuid": item_uuid, "image": mock_image}
        request = testing.DummyRequest(post=payload)
        request.registry = self.config.registry

        # set a dummy uuid to regis
        self.redis.hset('item_uuid_to_id', item_uuid, item.id)
        self.redis.expire(item_uuid, 3600)

        self.assertRaises(HTTPBadRequest, upload_item_images, request)
Ejemplo n.º 2
0
    def test_upload_item_images_post_id(self):
        """
        Test posting images for an item via id.
        """
        self._create_item_status()
        item = Item(name='iPhone', type='TRADE', quantity=1,
            description='A smart phone', status=self.draft_status,
            reason='just because')
        DBSession.add(item)
        DBSession.commit()

        uuid_filename = str(uuid.uuid4())
        mock_image = MockFileImage('image1.png')

        # write to disk the dummy image so the view can resize it
        original = '%s.png' % uuid_filename
        static_path = pkgr.resource_filename('tradeorsale', 'static')
        image_path = os.path.join(static_path,
            os.path.join('items/images', str(item.id)), original)
        with open(image_path, 'wb') as handle:
            handle.write(mock_image.file.read())
        self.failUnless(os.path.exists(image_path))

        # build request
        mock_image.file.seek(0)
        payload = {"item_id": item.id, "image": mock_image}
        request = testing.DummyRequest(post=payload)
        request.registry = self.config.registry

        response = upload_item_images(request)
        self.assertEqual(response.status_code, 200)

        # test that there are 3 images: original, small and medium
        self.assertEqual(DBSession.query(ItemImage).filter_by(item_id=item.id).count(), 3)
Ejemplo n.º 3
0
    def collection_get(self):
        """
        GET method for items collection, supports the following features:
        - item status filters
        - show more pagination
        """
        last_item_id = int(self.request.GET.get('last', 0))
        status_name = self.request.GET.get('status', None)

        # fetch user
        user_id = int(self.request.matchdict['user_id'])
        user = DBSession.query(User).filter_by(id=user_id).one()

        # filter status
        items = user.items
        if status_name:
            logger.info("filtering by status: %s" % status_name)
            status = DBSession.query(ItemStatus).filter_by(
                name=status_name.upper()).one()
            items = items.filter_by(status=status)

        # apply last item filtering if it exists
        if last_item_id:
            logger.info("filtering by last item id: %s" % last_item_id)
            items = items.filter(Item.id < last_item_id)

        # apply ordering
        items = items.order_by(Item.id.desc()).limit(DEFAULT_LIMIT)

        return [item.to_dict() for item in items]
Ejemplo n.º 4
0
 def _remove_existing_items(self):
     """
     Helper method to remove existing items.
     """
     for item in DBSession.query(Item).all():
         DBSession.delete(item)
     DBSession.commit()
Ejemplo n.º 5
0
def dashboard(request):
    draft, ongoing, archived = DBSession.query(ItemStatus).order_by(
        ItemStatus.id.asc()).all()

    # load draft items
    draft_items = DBSession.query(Item).filter_by(status=draft).order_by(
        Item.id.desc()).limit(PANEL_DEFAULT_PAGING)
    draft_items_json = _items_to_json(draft_items)

    # load ongoing items
    ongoing_items = DBSession.query(Item).filter_by(status=ongoing).order_by(
        Item.id.desc()).limit(PANEL_DEFAULT_PAGING)
    ongoing_items_json = _items_to_json(ongoing_items)

    # load archived items
    archived_items = DBSession.query(Item).filter_by(status=archived).order_by(
        Item.id.desc()).limit(PANEL_DEFAULT_PAGING)
    archived_items_json = _items_to_json(archived_items)

    return {
        'draft_items': draft_items_json,
        'ongoing_items': ongoing_items_json,
        'archived_items': archived_items_json,
        'body_class': 'plain-content'
    }
Ejemplo n.º 6
0
    def test_items_delete(self):
        """
        Test deleting an item.
        """
        # first create an item
        self._create_item_status()
        payload = {
            "name": "Macbook Air",
            "type": "TRADE",
            "quantity": "1",
            "price": "",
            "description": "Lightweight lappy.",
            "reason": "",
            "is_draft": "y",
            "uuid": str(uuid.uuid4())
        }

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        response = items(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(Item).count(), 1)

        # try retrieving the newly added item
        item = DBSession.query(Item).first()

        # now send a delete request
        request.method = 'DELETE'
        request.matchdict = {'id': item.id}
        request.body = None
        items(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(Item).count(), 0)
Ejemplo n.º 7
0
    def test_upload_item_images_post_uuid_failed(self):
        """
        Test posting images for an item via uuid with invalid image fails.
        """
        self._create_item_status()
        item = Item(name='iPhone', type='TRADE', quantity=1,
            description='A smart phone', status=self.draft_status,
            reason='just because')
        DBSession.add(item)
        DBSession.commit()

        class DumbMockImage(object):
            file = StringIO('image')
            filename = 'image1.jpg'

        item_uuid = str(uuid.uuid4())
        mock_image = DumbMockImage()

        payload = {"uuid": item_uuid, "image": mock_image}
        request = testing.DummyRequest(post=payload)
        request.registry = self.config.registry

        # set a dummy uuid to regis
        self.redis.hset('item_uuid_to_id', item_uuid, item.id)
        self.redis.expire(item_uuid, 3600)

        self.assertRaises(HTTPBadRequest, upload_item_images, request)
Ejemplo n.º 8
0
    def test_items_delete(self):
        """
        Test deleting an item.
        """
        # first create an item
        self._create_item_status()
        payload = {"name": "Macbook Air", "type": "TRADE", "quantity": "1",
                   "price": "", "description": "Lightweight lappy.",
                   "reason": "", "is_draft": "y", "uuid": str(uuid.uuid4())}

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        response = items(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(Item).count(), 1)

        # try retrieving the newly added item
        item = DBSession.query(Item).first()

        # now send a delete request
        request.method = 'DELETE'
        request.matchdict = {'id': item.id}
        request.body = None
        items(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(Item).count(), 0)
Ejemplo n.º 9
0
 def validate_status(self, request):
     status = request.GET.get('status', None)
     if status:
         try:
             DBSession.query(ItemStatus).filter_by(
                 name=status.upper()).one()
         except NoResultFound:
             request.errors.add('url', 'status', _(u'Invalid status'))
Ejemplo n.º 10
0
 def delete(self):
     item_id = int(self.request.matchdict['item_id'])
     item = DBSession.query(Item).filter_by(id=item_id).one()
     logger.info("deleting item: %s" % item_id)
     item.is_deleted = True
     DBSession.add(item)
     DBSession.commit()
     return {'status': 'success', 'message': _(u'Item deletion successful')}
Ejemplo n.º 11
0
 def validate_user(self, request):
     try:
         user_id = int(request.matchdict['user_id'])
         try:
             DBSession.query(User).filter_by(id=user_id).one()
         except NoResultFound:
             request.errors.add('url', 'user_id', _(u"User doesn't exist"))
     except ValueError:
         request.errors.add('url', 'user_id', _(u'Invalid User ID'))
Ejemplo n.º 12
0
 def delete(self):
     image_id = int(self.request.matchdict['image_id'])
     item_image = DBSession.query(ItemImage).filter_by(id=image_id).one()
     DBSession.delete(item_image)
     DBSession.commit()
     return {
         'status': 'success',
         'message': _(u'Image deletion successful')
     }
Ejemplo n.º 13
0
    def tearDown(self):
        testing.tearDown()

        # manually delete images path created by item because tearDown
        # disruptively drops table and no time to execute delete images event.
        self._remove_existing_items()

        DBSession.remove()
        Base.metadata.drop_all(self.engine)  # drop all tables
Ejemplo n.º 14
0
 def validate_item(self, request):
     try:
         user_id = int(request.matchdict['user_id'])
         item_id = int(request.matchdict['item_id'])
         try:
             DBSession.query(Item).filter_by(id=item_id,
                                             user_id=user_id).one()
         except NoResultFound:
             request.errors.add('url', 'item_id', _(u"Item doesn't exist"))
     except ValueError:
         request.errors.add('url', 'item_id', _(u'Invalid Item ID'))
Ejemplo n.º 15
0
 def validate_image(self, request):
     try:
         item_id = int(request.matchdict['item_id'])
         image_id = int(request.matchdict['image_id'])
         try:
             DBSession.query(ItemImage).filter_by(id=image_id,
                                                  item_id=item_id).one()
         except NoResultFound:
             request.errors.add('url', 'image_id',
                                _(u"Image doesn't exist"))
     except ValueError:
         request.errors.add('url', 'image_id', _(u'Invalid Image ID'))
Ejemplo n.º 16
0
    def test_items_put(self):
        """
        Test updating an item.
        """
        self._create_item_status()

        payload = {
            "name": "Macbook Air",
            "type": "TRADE",
            "quantity": "1",
            "price": "",
            "description": "Lightweight lappy.",
            "reason": "",
            "is_draft": "y",
            "uuid": str(uuid.uuid4())
        }

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        # make the request
        items(request)

        # try retrieving the newly added item
        item = DBSession.query(Item).first()
        self.failUnless(item)

        payload = {
            "name": "Macbook Pro",
            "type": "SALE",
            "quantity": "5",
            "price": "200.00",
            "description": "Lightweight lappy.",
            "reason": "",
            "is_draft": "n",
            "id": item.id
        }

        request.matchdict = {'id': item.id}
        request.method = 'PUT'
        request.body = json.dumps(payload)

        # make the request again
        response = items(request)
        self.assertEqual(response.status_code, 200)

        # reload item
        item = DBSession.query(Item).filter_by(id=item.id).first()
        self.assertEqual(item.name, payload['name'])
        self.assertEqual(item.type, payload['type'])
        self.assertEqual(item.quantity, int(payload['quantity']))
        self.assertEqual(str(item.price), payload['price'])
        self.assertEqual(item.status_id, self.draft_status.id)
Ejemplo n.º 17
0
def add_renderer_globals(event):
    request = event.get('request')
    if request is None:
        request = get_current_request()

    globs = {'h': helpers}

    if request is not None:
        globs['_'] = request.translate
        globs['localizer'] = request.localizer
        try:
            globs['session'] = request.session
        except ConfigurationError:
            pass

    def url(*args, **kwargs):
        """ route_url shorthand """
        return request.route_url(*args, **kwargs)

    tag_names = [tag.to_dict() for tag in DBSession.query(ItemTag).all()]

    globs['url'] = url
    globs['tag_names'] = json.dumps(tag_names)
    globs['post_item_form'] = ItemForm()

    event.update(globs)
Ejemplo n.º 18
0
def add_renderer_globals(event):
    request = event.get('request')
    if request is None:
        request = get_current_request()

    globs = {'h': helpers}

    if request is not None:
        globs['_'] = request.translate
        globs['localizer'] = request.localizer
        try:
            globs['session'] = request.session
        except ConfigurationError:
            pass

    def url(*args, **kwargs):
        """ route_url shorthand """
        return request.route_url(*args, **kwargs)

    tag_names = [tag.to_dict() for tag in DBSession.query(ItemTag).all()]

    globs['url'] = url
    globs['tag_names'] = json.dumps(tag_names)
    globs['post_item_form'] = ItemForm()

    event.update(globs)
Ejemplo n.º 19
0
 def _create_item_status(self):
     """
     Helper method to create item statuses.
     """
     self.draft_status = ItemStatus('DRAFTS')
     self.ongoing_status = ItemStatus('ONGOING')
     self.archived_status = ItemStatus('ARCHIVED')
     DBSession.add(self.draft_status)
     DBSession.add(self.ongoing_status)
     DBSession.add(self.archived_status)
     DBSession.commit()
Ejemplo n.º 20
0
    def test_upload_item_images_post_uuid(self):
        """
        Test posting images for an item via uuid.
        """
        self._create_item_status()
        item = Item(name='iPhone',
                    type='TRADE',
                    quantity=1,
                    description='A smart phone',
                    status=self.draft_status,
                    reason='just because')
        DBSession.add(item)
        DBSession.commit()

        item_uuid = str(uuid.uuid4())
        mock_image = MockFileImage('image1.png')

        # write to disk the dummy image so the view can resize it
        original = '%s.png' % item_uuid
        static_path = pkgr.resource_filename('tradeorsale', 'static')
        image_path = os.path.join(static_path,
                                  os.path.join('items/images', str(item.id)),
                                  original)
        with open(image_path, 'wb') as handle:
            handle.write(mock_image.file.read())
        self.failUnless(os.path.exists(image_path))

        # build request
        mock_image.file.seek(0)
        payload = {"uuid": item_uuid, "image": mock_image}
        request = testing.DummyRequest(post=payload)
        request.registry = self.config.registry

        # set a dummy uuid to regis
        self.redis.hset('item_uuid_to_id', item_uuid, item.id)
        self.redis.expire(item_uuid, 3600)

        response = upload_item_images(request)
        self.assertEqual(response.status_code, 200)

        # test that there are 3 images: original, small and medium
        self.assertEqual(
            DBSession.query(ItemImage).filter_by(item_id=item.id).count(), 3)
Ejemplo n.º 21
0
    def test_create_image_path(self):
        """
        Test that creating an item creates image path.
        """
        self._create_item_status()
        item = Item(name='iPhone',
                    type='TRADE',
                    quantity=1,
                    description='A smart phone',
                    status=self.draft_status,
                    reason='just because')
        DBSession.add(item)
        DBSession.commit()

        # check that the images path has been created
        images_path = pkgr.resource_filename('tradeorsale', 'static')
        item_images_abspath = os.path.join(
            images_path, os.path.join('items/images', str(item.id)))
        self.failUnless(os.path.exists(item_images_abspath))
Ejemplo n.º 22
0
    def test_dashboard_view_drafts_nonempty(self):
        """
        Test that dashboard view returns non-empty list
        draft items when there are draft items.
        """
        self._create_item_status()
        DBSession.add(
            Item(name='iPhone',
                 type='TRADE',
                 description='A smart phone.',
                 status=self.draft_status,
                 quantity=1))
        DBSession.add(
            Item(name='Macbook Pro',
                 type='SALE',
                 description='An apple product.',
                 price=30500,
                 status=self.ongoing_status,
                 quantity=5))
        DBSession.commit()

        request = testing.DummyRequest()
        response = dashboard(request)
        draft_items = json.loads(response['draft_items'])

        self.assertEqual(len(draft_items), 1)
        self.assertNotEqual(draft_items, [])
Ejemplo n.º 23
0
    def test_items_put(self):
        """
        Test updating an item.
        """
        self._create_item_status()

        payload = {"name": "Macbook Air", "type": "TRADE", "quantity": "1",
                   "price": "", "description": "Lightweight lappy.",
                   "reason": "", "is_draft": "y", "uuid": str(uuid.uuid4())}

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        # make the request
        items(request)

        # try retrieving the newly added item
        item = DBSession.query(Item).first()
        self.failUnless(item)

        payload = {"name": "Macbook Pro", "type": "SALE", "quantity": "5",
                   "price": "200.00", "description": "Lightweight lappy.",
                   "reason": "", "is_draft": "n", "id": item.id}

        request.matchdict = {'id': item.id}
        request.method = 'PUT'
        request.body = json.dumps(payload)

        # make the request again
        response = items(request)
        self.assertEqual(response.status_code, 200)

        # reload item
        item = DBSession.query(Item).filter_by(id=item.id).first()
        self.assertEqual(item.name, payload['name'])
        self.assertEqual(item.type, payload['type'])
        self.assertEqual(item.quantity, int(payload['quantity']))
        self.assertEqual(str(item.price), payload['price'])
        self.assertEqual(item.status_id, self.draft_status.id)
Ejemplo n.º 24
0
    def test_items_post_failed(self):
        """
        Test that when POSTing malformed payload, it'll raise HTTPBadRequest.
        """
        payload = {"name": "", "type": "", "quantity": "",
                   "price": "", "description": "", "reason": "",
                   "is_draft": "", "uuid": ""}

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        self.assertRaises(HTTPBadRequest, items, request)
        self.assertEqual(DBSession.query(Item).count(), 0)
Ejemplo n.º 25
0
def dashboard(request):
    draft, ongoing, archived = DBSession.query(
        ItemStatus).order_by(ItemStatus.id.asc()).all()

    # load draft items
    draft_items = DBSession.query(Item).filter_by(
        status=draft).order_by(Item.id.desc()).limit(PANEL_DEFAULT_PAGING)
    draft_items_json = _items_to_json(draft_items)

    # load ongoing items
    ongoing_items = DBSession.query(Item).filter_by(
        status=ongoing).order_by(Item.id.desc()).limit(PANEL_DEFAULT_PAGING)
    ongoing_items_json = _items_to_json(ongoing_items)

    # load archived items
    archived_items = DBSession.query(Item).filter_by(
        status=archived).order_by(Item.id.desc()).limit(PANEL_DEFAULT_PAGING)
    archived_items_json = _items_to_json(archived_items)

    return {'draft_items': draft_items_json,
            'ongoing_items': ongoing_items_json,
            'archived_items': archived_items_json,
            'body_class': 'plain-content'}
Ejemplo n.º 26
0
    def test_items_post(self):
        """
        Test creation of new item by POSTing.
        """
        payload = {"name": "Macbook Air", "type": "TRADE", "quantity": "1",
                   "price": "", "description": "Lightweight lappy.",
                   "reason": "", "is_draft": "y", "uuid": str(uuid.uuid4())}

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        response = items(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(Item).count(), 1)
Ejemplo n.º 27
0
    def test_items_put_failed(self):
        """
        Test that updating non-existent item fails.
        """
        payload = {"name": "Macbook Pro", "type": "SALE", "quantity": "5",
                   "price": "200.00", "description": "Lightweight lappy.",
                   "reason": "", "is_draft": "n", "id": 1}

        request = Request({}, method='PUT', body=json.dumps(payload))
        request.registry = self.config.registry
        request.matchdict = {'id': 1}
        request.method = 'PUT'

        self.assertRaises(HTTPBadRequest, items, request)
        self.assertEqual(DBSession.query(Item).count(), 0)
Ejemplo n.º 28
0
    def test_item_image_delete(self):
        """
        Test that image is deleted when DELETE request is sent.
        """
        self._create_item_status()
        item = Item(name='iPhone',
                    type='TRADE',
                    quantity=1,
                    description='A smart phone',
                    status=self.draft_status,
                    reason='just because')
        DBSession.add(item)
        DBSession.commit()

        # write to disk the dummy image
        mock_image = MockFileImage('original.jpg')
        static_path = pkgr.resource_filename('tradeorsale', 'static')
        item_images_path = os.path.join(
            static_path, os.path.join('items/images', str(item.id)))
        image_path = os.path.join(item_images_path, mock_image.filename)
        with open(image_path, 'wb') as handle:
            handle.write(mock_image.file.read())
        self.failUnless(os.path.exists(image_path))

        # save the image in db
        item_image = ItemImage(
            item.id, mock_image.filename,
            os.path.join('/%s' % item_images_path, mock_image.filename))
        DBSession.add(item_image)
        DBSession.commit()

        # send DELETE request
        request = Request({}, method='DELETE')
        request.matchdict = {'id': item.id}
        request.registry = self.config.registry

        # check that record was deleted
        response = item_images(None, request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(ItemImage).count(), 0)
        self.failUnless(not os.path.exists(image_path))
Ejemplo n.º 29
0
    def test_item_image_delete(self):
        """
        Test that image is deleted when DELETE request is sent.
        """
        self._create_item_status()
        item = Item(name='iPhone', type='TRADE', quantity=1,
            description='A smart phone', status=self.draft_status,
            reason='just because')
        DBSession.add(item)
        DBSession.commit()

        # write to disk the dummy image
        mock_image = MockFileImage('original.jpg')
        static_path = pkgr.resource_filename('tradeorsale', 'static')
        item_images_path = os.path.join(static_path,
            os.path.join('items/images', str(item.id)))
        image_path = os.path.join(item_images_path, mock_image.filename)
        with open(image_path, 'wb') as handle:
            handle.write(mock_image.file.read())
        self.failUnless(os.path.exists(image_path))

        # save the image in db
        item_image = ItemImage(item.id, mock_image.filename,
            os.path.join('/%s' % item_images_path, mock_image.filename))
        DBSession.add(item_image)
        DBSession.commit()

        # send DELETE request
        request = Request({}, method='DELETE')
        request.matchdict = {'id': item.id}
        request.registry = self.config.registry

        # check that record was deleted
        response = item_images(None, request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(ItemImage).count(), 0)
        self.failUnless(not os.path.exists(image_path))
Ejemplo n.º 30
0
    def test_items_post_failed(self):
        """
        Test that when POSTing malformed payload, it'll raise HTTPBadRequest.
        """
        payload = {
            "name": "",
            "type": "",
            "quantity": "",
            "price": "",
            "description": "",
            "reason": "",
            "is_draft": "",
            "uuid": ""
        }

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        self.assertRaises(HTTPBadRequest, items, request)
        self.assertEqual(DBSession.query(Item).count(), 0)
Ejemplo n.º 31
0
    def test_items_post(self):
        """
        Test creation of new item by POSTing.
        """
        payload = {
            "name": "Macbook Air",
            "type": "TRADE",
            "quantity": "1",
            "price": "",
            "description": "Lightweight lappy.",
            "reason": "",
            "is_draft": "y",
            "uuid": str(uuid.uuid4())
        }

        request = Request({}, method='POST', body=json.dumps(payload))
        request.registry = self.config.registry

        response = items(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(DBSession.query(Item).count(), 1)
Ejemplo n.º 32
0
    def test_items_put_failed(self):
        """
        Test that updating non-existent item fails.
        """
        payload = {
            "name": "Macbook Pro",
            "type": "SALE",
            "quantity": "5",
            "price": "200.00",
            "description": "Lightweight lappy.",
            "reason": "",
            "is_draft": "n",
            "id": 1
        }

        request = Request({}, method='PUT', body=json.dumps(payload))
        request.registry = self.config.registry
        request.matchdict = {'id': 1}
        request.method = 'PUT'

        self.assertRaises(HTTPBadRequest, items, request)
        self.assertEqual(DBSession.query(Item).count(), 0)
Ejemplo n.º 33
0
    def test_dashboard_view_drafts_nonempty(self):
        """
        Test that dashboard view returns non-empty list
        draft items when there are draft items.
        """
        self._create_item_status()
        DBSession.add(Item(name='iPhone', type='TRADE',
            description='A smart phone.', status=self.draft_status, quantity=1))
        DBSession.add(Item(name='Macbook Pro', type='SALE',
            description='An apple product.', price=30500,
            status=self.ongoing_status, quantity=5))
        DBSession.commit()

        request = testing.DummyRequest()
        response = dashboard(request)
        draft_items = json.loads(response['draft_items'])

        self.assertEqual(len(draft_items), 1)
        self.assertNotEqual(draft_items, [])
Ejemplo n.º 34
0
    def collection_post(self):
        payload = MultiDict(self.request.json_body)

        # fetch user
        # TODO: assign currently logged-in user's id
        user = DBSession.query(User).filter_by(id=1).one()

        # fetch status
        status_name = 'DRAFTS' if payload.get('is_draft', False) else 'ONGOING'
        status = DBSession.query(ItemStatus).filter_by(name=status_name).one()

        qty = int(payload.get('quantity', 1))
        price = payload['price'] if payload.get(
            'price', None) and payload['price'] else None
        new_item = Item(user=user,
                        name=payload['name'],
                        type=payload['type'],
                        trade_with=payload.get('trade_with', None),
                        status=status,
                        price=price,
                        quantity=qty,
                        description=payload['description'],
                        reason=payload['reason'])

        # load assigned tags and extend new item's tags
        if payload.get('tags', None):
            tag_ids = [
                tag['id'] for tag in payload['tags'] if tag.get('id', None)
            ]
            tags = DBSession.query(ItemTag).filter(
                ItemTag.id.in_(tag_ids)).all()
            new_item.tags.extend(tags)

        DBSession.add(new_item)
        DBSession.commit()

        return new_item.to_dict()
Ejemplo n.º 35
0
    def test_delete_image(self):
        """
        Test that deleting an image deletes it from disk.
        """
        # create item first
        self._create_item_status()
        item = Item(name='iPhone',
                    type='TRADE',
                    quantity=1,
                    description='A smart phone',
                    status=self.draft_status,
                    reason='just because')
        DBSession.add(item)
        DBSession.commit()

        # write to disk the dummy image
        mock_image = MockFileImage('original.jpg')
        static_path = pkgr.resource_filename('tradeorsale', 'static')
        item_images_path = os.path.join(
            static_path, os.path.join('items/images', str(item.id)))
        image_path = os.path.join(item_images_path, mock_image.filename)
        with open(image_path, 'wb') as handle:
            handle.write(mock_image.file.read())
        self.failUnless(os.path.exists(image_path))

        # save the image in db
        item_image = ItemImage(
            item.id, mock_image.filename,
            os.path.join('/%s' % item_images_path, mock_image.filename))
        DBSession.add(item_image)
        DBSession.commit()

        # delete image and check that it doesn't exist
        DBSession.delete(item_image)
        DBSession.commit()
        self.failUnless(not os.path.exists(image_path))
Ejemplo n.º 36
0
    def put(self):
        item_id = int(self.request.matchdict['item_id'])
        payload = MultiDict(self.request.json_body)
        item = DBSession.query(Item).filter_by(id=item_id).one()
        transaction_date = None

        print payload

        # fetch status
        if payload.get('is_draft', False):
            status_name = 'DRAFTS'
        elif payload.get('status', None) and payload['status'] == 'archived':
            status_name = 'ARCHIVED'
            transaction_date = datetime.now()
        else:
            status_name = 'ONGOING'
        status = DBSession.query(ItemStatus).filter_by(name=status_name).one()

        # fetch new tags
        new_tags = []
        ids_to_add = [
            int(tag['id']) for tag in payload.get('tags', [])
            if tag.get('id', None)
        ]
        if ids_to_add:
            new_tags.extend(
                DBSession.query(ItemTag).filter(
                    ItemTag.id.in_(ids_to_add)).all())

        item.tags = new_tags  # replace existing tags
        new_qty = int(payload.get('quantity', 1))
        price = payload['price'] if payload['price'] else None

        item.name = payload['name']
        item.type = payload['type']
        item.trade_with = payload.get('trade_with', None)
        item.status = status
        item.price = price
        item.description = payload['description']
        item.reason = payload.get('reason', None)
        item.transaction_date = transaction_date

        # adjust original quantity
        if new_qty > item.quantity:
            additional_quantity = new_qty - item.quantity
            item.original_quantity += additional_quantity
        elif new_qty < item.quantity:
            additional_quantity = item.quantity - new_qty
            item.original_quantity -= additional_quantity

        item.quantity = new_qty

        updating_fields = ('updating item: %s', 'name: %s', 'type: %s',
                           'status: %s', 'price: %s', 'quantity: %s',
                           'description: %s', 'reason: %s', 'tags: %s',
                           'transaction date: %s\n')
        logger.info('\n'.join(updating_fields) %
                    (item_id, item.name, item.type, item.status, item.price,
                     item.quantity, item.description, item.reason, item.tags,
                     item.transaction_date))

        DBSession.commit()
        return item.to_dict()
Ejemplo n.º 37
0
    def get(self):
        """
        GET method for fetching single item.
        """
        action = self.request.GET.get('action', None)
        item_id = int(self.request.matchdict['item_id'])
        item = DBSession.query(Item).filter_by(id=item_id).one()

        if action and action == 'clone':
            logger.info("cloning item: %s" % str(item_id))
            draft_status = DBSession.query(ItemStatus).filter_by(
                name='DRAFTS').one()
            cloned_item = Item(user=item.user,
                               name='%s - copy' % item.name,
                               type=item.type,
                               quantity=item.quantity,
                               description=item.description,
                               status=draft_status,
                               price=item.price,
                               reason=item.reason)
            cloned_item.tags = item.tags
            DBSession.add(cloned_item)
            DBSession.commit()

            # clone images
            static_path = pkgr.resource_filename('tradeorsale', 'static')
            source = os.path.join(static_path, 'items/images/%s' % item_id)
            destination = os.path.join(static_path,
                                       'items/images/%s' % cloned_item.id)

            try:
                for imgfile in os.listdir(source):
                    shutil.copy(os.path.join(source, imgfile), destination)
                for image in item.images.filter_by(parent=None).all():
                    segments = image.path.split('/')
                    segments[3] = str(cloned_item.id)
                    original_img = ItemImage(item=cloned_item,
                                             name=image.name,
                                             path='/'.join(segments))
                    for subimage in image.subimages.all():
                        segments = subimage.path.split('/')
                        segments[3] = str(cloned_item.id)
                        sub_img = ItemImage(item=cloned_item,
                                            name=subimage.name,
                                            path='/'.join(segments),
                                            size=subimage.size,
                                            parent=original_img)
                        DBSession.add(sub_img)
                    DBSession.add(original_img)
            except OSError as e:
                logger.error("error while cloning images: %s" % str(e))

            DBSession.commit()
            return cloned_item.to_dict()

        return item.to_dict()
Ejemplo n.º 38
0
    def collection_post(self):
        item_id = int(self.request.matchdict['item_id'])
        item = DBSession.query(Item).filter_by(id=item_id).one()
        ext = os.path.splitext(
            self.request.POST['image'].filename)[1] or '.jpg'
        filename_uuid = uuid.uuid4()
        filename = '%s%s' % (filename_uuid, ext)

        # figure out path to the newly uploaded image
        static_path = pkgr.resource_filename('tradeorsale', 'static')
        item_images_path = os.path.join('items/images', str(item_id))
        item_images_abspath = os.path.join(static_path, item_images_path)
        image_path = os.path.join(item_images_abspath, filename)

        # copy file chunk by chunk
        with open(image_path, 'wb') as handle:
            while True:
                data = self.request.POST['image'].file.read(2 << 16)  # 128kb
                if not data:
                    break
                handle.write(data)

        logger.info("storing item image to db: item-id(%i) size(original)" %
                    item_id)
        item_image = ItemImage(item, filename,
                               os.path.join('/%s' % item_images_path,
                                            filename))  # / + items/...

        # build resized images
        image_sizes = {}
        for size, dimension in THUMBNAIL_SIZES.items():
            resized_filename = '%s_%s%s' % (filename_uuid, size, ext)
            resized_image_path = os.path.join(item_images_abspath,
                                              resized_filename)

            # resize image
            logger.info("resizing image to %s" % str(THUMBNAIL_SIZES[size]))

            try:
                img = Image.open(image_path)
            except IOError as e:
                logger.error("unable to open image: %s" % str(e))
                self.request.errors.add('body', 'image',
                                        _(u'Unable to read image'))

            # if we're resizing to medium size, make height relative to width
            if size == 'medium':
                basewidth = THUMBNAIL_SIZES[size][0]
                width_percentage = (basewidth / float(img.size[0]))
                height_size = int(
                    (float(img.size[1]) * float(width_percentage)))
                resized_img = img.resize((basewidth, height_size),
                                         Image.ANTIALIAS)
            else:
                resized_img = ImageOps.fit(img, THUMBNAIL_SIZES[size],
                                           Image.ANTIALIAS)
            resized_img.save(resized_image_path, quality=90, optimize=True)

            # save resized image to db
            logger.info("storing item image to db: item-id(%i) size(%s)" %
                        (item_id, size))
            item_subimage = ItemImage(
                item, resized_filename,
                os.path.join('/%s' % item_images_path, resized_filename), size)
            item_image.subimages.append(item_subimage)

        # save original image to db
        DBSession.add(item_image)
        DBSession.commit()

        # return different images sizes
        image_sizes = {
            'id': item_image.id,
            'original': assets_url(self.request, item_image.path)
        }
        for size in THUMBNAIL_SIZES.keys():
            image_sizes[size] = assets_url(self.request,
                                           item_image.get_resized_image(size))

        return {'item_id': item_id, 'sizes': image_sizes}