Esempio n. 1
0
    def test_upload_an_image(self, ImageTruck, delay):
        truck = Mock()
        ImageTruck.new_from_stream.return_value = truck
        truck.filename = 'CA7'
        truck.url.return_value = 'ess three'
        truck.contents = b''
        truck.content_type = "image/jpeg"

        session = Client().session()
        album = Album(name='11:11 Eleven Eleven')
        session.add(album)
        session.flush()

        response = self.app.post('/add', data={
            'url': '',
            'album_id': album.album_id,
            'file': (StringIO(str('booya')), 'img.jpg')})

        image = session.query(Image).one()

        eq_(image.filename, 'CA7')
        eq_(image.source_url, '')
        eq_(image.album_id, album.album_id)

        eq_(response.status_code, 302, response.data)
        eq_(response.headers['Location'],
            'http://localhost/image/{0}'.format(image.image_id))

        contents = session.query(ImageContents).one()
        eq_(image.image_id, contents.image_id)

        delay.assert_called_with(
                [], process_image, contents.image_contents_id)
Esempio n. 2
0
    def test_upload_an_image_twice(self, ImageTruck, delay):
        truck = Mock()
        ImageTruck.new_from_stream.return_value = truck
        truck.filename = 'CA7'
        truck.url.return_value = 'ess three'
        truck.contents = b''
        truck.content_type = "image/jpeg"

        response = self.app.post('/add', data={
            'url': '',
            'file': (StringIO(str('booya')), 'img.jpg')})
        eq_(response.status_code, 302)
        response = self.app.post('/add', data={
            'url': '',
            'file': (StringIO(str('booya')), 'img.jpg')})
        eq_(response.status_code, 302)

        session = Client().session()
        image = session.query(Image).one()
        contentses = session.query(ImageContents).all()
        for contents in contentses:
            eq_(contents.image_id, image.image_id)
        contents_calls = [call([], process_image, x.image_contents_id)
                          for x in contentses]
        delay.assert_has_calls(contents_calls)
Esempio n. 3
0
    def test_upload_an_image_with_json_format(self, ImageTruck, delay):
        truck = Mock()
        ImageTruck.new_from_url.return_value = truck
        truck.filename = 'CA741C'
        truck.url.return_value = 'cloudfrunt.nut/CA741C'
        truck.contents = b''
        truck.content_type = "image/gif"

        task_id = str(uuid.uuid4())
        delay.return_value = task_id

        response = self.app.post('/add.json', data={
            'album': '',
            'url': 'imgur.com/cool_cat.gif'})
        eq_(response.status_code, 200, response.data)

        session = Client().session()
        image = session.query(Image).one()
        body = json.loads(response.data)

        eq_(body,
            [{
                'url': 'cloudfrunt.nut/CA741C',
                'image_id': image.image_id,
                'task_id': task_id,
            }])
        contents = session.query(ImageContents).one()
        eq_(contents.image_id, image.image_id)
        delay.assert_called_with([],
                                 process_image,
                                 contents.image_contents_id)
Esempio n. 4
0
    def test_upload_an_image_twice(self,
                                   ImageTruck,
                                   ImageMetadata,
                                   ResizeImage):
        truck = Mock()
        ImageTruck.new_from_stream.return_value = truck
        truck.calculate_filename.return_value = 'CA7'
        truck.calculate_filename.return_value = 'CA7'
        truck.url.return_value = 'ess three'
        ImageMetadata.image_metadata.return_value = {}

        response = self.app.post('/add', data={
            'tags': 'pet',
            'url': '',
            'album': '',
            'file': (StringIO(str('booya')), 'img.jpg')})
        eq_(response.status_code, 302)
        response = self.app.post('/add', data={
            'tags': 'pet',
            'url': '',
            'album': '',
            'file': (StringIO(str('booya')), 'img.jpg')})
        eq_(response.status_code, 302)

        session = Client().session()
        image = session.query(Image).one()
        image_tags = session.query(ImageTag.image_id).all()
        eq_(image_tags, [(image.image_id,)])
Esempio n. 5
0
    def test_add_and_remove_a_tag(self):
        session = Client().session()
        image = Image(filename='bab1e5')
        session.add(image)
        session.flush()
        self.visit_url('/image/%d' % image.image_id)
        assert self.browser.is_text_present('(click to add a tag)'),\
            "Didn't find tag-adder"
        add_tag = self.browser.find_by_css('#add-tag')
        add_tag.click()
        tag_name = self.browser.find_by_css('li input')
        tag_name.fill("booya\n")

        new_tag = self.browser.find_by_css('li span').first
        eq_(new_tag.text, 'booya')

        assert self.browser.is_text_present('(click to add a tag)'),\
            "Didn't find new tag-adder"

        image_tag = session.query(ImageTag).\
                join(Tag, Tag.tag_id == ImageTag.tag_id).\
                filter(Tag.name == 'booya').\
                one()
        eq_(image_tag.image_id, image.image_id)

        self.browser.find_link_by_text('x').first.click()

        assert not self.browser.is_text_present('booya'), \
            "Tag wasn't deleted from the page"

        image_tags = session.query(ImageTag).all()
        eq_(image_tags, [])
Esempio n. 6
0
def process_image(self, image_contents_id):
    session = Client().session()
    contents = session.query(ImageContents).\
        filter(ImageContents.image_contents_id == image_contents_id).\
        one()

    image = session.query(Image).\
        filter(Image.image_id == contents.image_id).\
        one()

    truck = ImageTruck(
        contents.contents, contents.content_type, image.source_url)
    truck.filename = image.filename
    metadata = ImageMetadata.image_metadata(truck.contents)
    truck.contents = ReorientImage.reorient_image(truck.contents)
    def after_upload(size):
        redis.publish(REDIS_CHANNEL, json.dumps({
            'task_id': self.request.id,
            'suffix': size,
        }))
    ResizeImage.make_resizes(image, truck, after_upload)

    print "uploading original image"
    truck.upload()
    redis.publish(REDIS_CHANNEL, json.dumps({
        'task_id': self.request.id,
        'suffix': '',
    }))

    delay(queued_tasks, Invalidate(), image.image_id)

    for attr, value in metadata.iteritems():
        setattr(image, attr, value)
    session.add(image)
    session.delete(contents)
Esempio n. 7
0
def show_image(request_format, image_id, size):
    session = Client().session()
    image = session.query(Image).\
        filter(Image.image_id == image_id).\
        one()
    if g.user:
        albums = session.query(Album).all()
    else:
        albums = []
    if image.album_id is not None:
        album = session.query(Album).\
            filter(Album.album_id == image.album_id).\
            one()
    else:
        album = None
    (prev, next) = image.neighbors()
    resizes = session.query(ImageResize).\
        filter(ImageResize.image_id == image_id).\
        order_by(ImageResize.width.asc()).\
        all()
    url = ImageTruck.url_for_filename(image.filename)

    if resizes and size in [r.suffix for r in resizes]:
        url = '{0}_{1}'.format(url, size)

    tags = image.get_tags()
    if request_format == 'html':
        return render_template('image.html.jinja',
                               image=image,
                               prev=prev,
                               next=next,
                               album=album,
                               albums=albums,
                               url=url,
                               tags=list(tags),
                               metadata_fields=filter(lambda (x,_): getattr(image, x), Image.metadata_fields),
                               getattr=getattr,
                               resizes=resizes,
                               size=size)
    elif request_format == 'json':
        return {
            'description': image.description,
            'title': image.title,
            'camera': image.camera,
            'photographed_at': image.photographed_at,
            'focal_length': image.focal_length,
            'aperture': image.aperture,
            'shutter_speed': image.shutter_speed,
            'iso': image.iso,
            'album_id': image.album_id,
            'tags': list(tags),
            'source_url': url,
        }
Esempio n. 8
0
def show_image(request_format, image_id, size):
    session = Client().session()
    image = session.query(Image).filter(Image.image_id == image_id).one()
    if g.user:
        albums = session.query(Album).all()
    else:
        albums = []
    if image.album_id is not None:
        album = session.query(Album).filter(Album.album_id == image.album_id).one()
    else:
        album = None
    (prev, next) = image.neighbors()
    resizes = (
        session.query(ImageResize).filter(ImageResize.image_id == image_id).order_by(ImageResize.width.asc()).all()
    )
    url = ImageTruck.url_for_filename(image.filename)

    if resizes and size in [r.suffix for r in resizes]:
        url = "{0}_{1}".format(url, size)

    tags = image.get_tags()
    if request_format == "html":
        return render_template(
            "image.html.jinja",
            image=image,
            prev=prev,
            next=next,
            album=album,
            albums=albums,
            url=url,
            tags=list(tags),
            metadata_fields=filter(lambda (x, _): getattr(image, x), Image.metadata_fields),
            getattr=getattr,
            resizes=resizes,
            size=size,
        )
    elif request_format == "json":
        return {
            "description": image.description,
            "title": image.title,
            "camera": image.camera,
            "photographed_at": image.photographed_at,
            "focal_length": image.focal_length,
            "aperture": image.aperture,
            "shutter_speed": image.shutter_speed,
            "iso": image.iso,
            "album_id": image.album_id,
            "tags": list(tags),
            "source_url": url,
        }
Esempio n. 9
0
def show_add(request_format):
    session = Client().session()
    albums = session.query(Album).all()
    if request_format == 'html':
        return render_template('add.html.jinja', user=g.user, albums=albums)
    elif request_format == 'json':
        return {'albums': albums}
Esempio n. 10
0
def show_add(request_format):
    session = Client().session()
    albums = session.query(Album).all()
    if request_format == "html":
        return render_template("add.html.jinja", albums=albums)
    elif request_format == "json":
        return {"albums": albums}
Esempio n. 11
0
    def test_image_resizes_do_upserts(self):
        session = Client().session()
        image = Image(filename='ac1d1c')
        session.add(image)
        session.flush()

        resize = ImageResize(
            image_id=image.image_id,
            width=15,
            height=15,
            suffix="little")
        session.add(resize)
        session.flush()

        resize = ImageResize(
            image_id=image.image_id,
            width=15,
            height=15,
            suffix="small")
        session.add(resize)
        session.flush()

        resize = session.query(ImageResize).\
            filter(ImageResize.image_id == image.image_id).\
            one()
        eq_('small', resize.suffix)
Esempio n. 12
0
    def test_edit_the_description(self):
        session = Client().session()
        image = Image(filename='deafbeef')
        session.add(image)
        session.flush()
        self.visit_url('/image/%d' % image.image_id)
        assert self.browser.is_text_present('(click to add description)'), \
            "Didn't find description placeholder"

        description = self.browser.find_by_css('#description span')
        assert description, "Didn't find description"
        description.click()
        description_edit = self.browser.find_by_css('#description textarea')
        assert description_edit, "Didn't find a description-edit field!"
        eq_(description_edit.value, '(click to add description)')
        description_edit.fill("this image fills me with glee\t")

        description = self.browser.find_by_css('#description span')
        assert description, "Didn't find description after editing"
        description.click()
        description_edit = self.browser.find_by_css('#description textarea')
        assert description_edit, "Didn't find a description-edit field after editing"
        eq_(description_edit.value, 'this image fills me with glee')
        description_edit.fill("this image makes me sad\t")

        image = session.query(Image).\
                filter(Image.image_id == image.image_id).\
                one()
        eq_(image.description, 'this image makes me sad')
Esempio n. 13
0
    def test_edit_the_title(self):
        session = Client().session()
        image = Image(filename='asdf', title='click on this!')
        session.add(image)
        session.flush()
        self.visit_url('/image/%d' % image.image_id)
        assert self.browser.is_text_present('click on this!'), \
            "Didn't find expected title"

        title = self.browser.find_by_css('h2').first
        assert title, "Didn't find a title"
        title.click()
        title_edit_field = self.browser.find_by_css('header input')
        assert title_edit_field, "Didn't find a title-edit field!"
        eq_(title_edit_field.value, 'click on this!')
        title_edit_field.fill('I clicked\n')

        title = self.browser.find_by_css('h2').first
        assert title, "Didn't find a title after first edit"
        title.click()
        title_edit_field = self.browser.find_by_css('header input')
        assert title_edit_field, "didn't find a title-edit field after first edit"
        eq_(title_edit_field.value, 'I clicked')
        title_edit_field.fill("I clicked TWICE\n")

        image = session.query(Image).\
                filter(Image.image_id == image.image_id).\
                one()
        eq_(image.title, 'I clicked TWICE')
Esempio n. 14
0
    def test_change_album(self):
        session = Client().session()
        image = Image(filename='deadbeef')
        session.add(image)
        migrant = Album(name='migrant')
        pink_friday = Album(name="Pink Friday")
        session.add(migrant)
        session.add(pink_friday)
        session.flush()

        self.visit_url('/image/%d' % image.image_id)
        assert self.browser.is_text_present('image has no album')
        assert self.browser.is_text_present('set album')

        set_album = self.browser.find_by_css('#set-album').first
        set_album.click()
        self.browser.select('album', pink_friday.album_id)
        assert self.browser.is_text_present(
            "image appears in the album 'Pink Friday'"),\
            "Album info wasn't present"

        del image
        image = session.query(Image).one()
        eq_(image.album_id, pink_friday.album_id)

        self.visit_url('/image/%d' % image.image_id)
        assert self.browser.is_text_present(
            "image appears in the album 'Pink Friday'"),\
            "Album info wasn't right after reload"
Esempio n. 15
0
    def test_update_an_image(self):
        session = Client().session()
        album = Album(name='cow shots')
        session.add(album)
        image = Image(filename='deadbeef',
                      description='one time I saw a dead cow',
                      title='dead beef')

        session.add(image)
        session.flush()

        response = self.app.patch('/image/%d.json' % image.image_id, data={
            'album_id': album.album_id,
        })
        body = json.loads(response.data)
        eq_(body, {
            'status': 'ok',
            'image': {
                'title': 'dead beef',
                'description': 'one time I saw a dead cow',
                'album_id': str(album.album_id),
                'caption': 'dead beef',
                'tags': [],
            }
        })

        del image
        image = session.query(Image).one()
        eq_(image.album_id, album.album_id)
Esempio n. 16
0
    def test_upload_an_image(self, ImageTruck, ResizeImage, ImageMetadata):
        truck = Mock()
        ImageTruck.new_from_stream.return_value = truck
        truck.calculate_filename.return_value = 'CA7'
        truck.url.return_value = 'ess three'
        ImageMetadata.image_metadata.return_value = {
            'camera': 'Samsung NX210',
            'photographed_at': '2013-05-09 12:00:00',
            'focal_length': 30,
            'aperture': '1/1.8',
            'shutter_speed': 5,
            'iso': '400'}

        response = self.app.post('/add', data={
            'album': '',
            'tags': 'pet cool',
            'url': '',
            'title': 'My cat being awesome',
            'description': 'my cat is awesome. You can see how awesome.',
            'file': (StringIO(str('booya')), 'img.jpg')})

        session = Client().session()
        image = session.query(Image).one()

        eq_(image.filename, 'CA7')
        eq_(image.source_url, '')
        eq_(image.title, 'My cat being awesome')
        eq_(image.description, 'my cat is awesome. You can see how awesome.')

        ResizeImage.make_resizes.assert_called_with(image, truck)

        eq_(response.status_code, 302, response.data)
        eq_(response.headers['Location'],
            'http://localhost/image/%d' % image.image_id)
Esempio n. 17
0
    def run(self, image_id, suffix=None):
        session = Client().session()
        now = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
        try:
            image = session.query(Image).\
                filter((Image.created_at - timedelta(hours=1)) < now).\
                filter(Image.image_id == image_id).\
                one()
        except NoResultFound:
            session.rollback()
            logger.error('No unexpired result found for image_id {0}. '
                         'Skipping.'.format(image_id))
            return

        filename = image.filename
        print repr(suffix)
        if suffix is not None:
            filename = '{0}_{1}'.format(filename, suffix)

        config = Client().config()
        try:
            distro_id = config['aws.cloudfront_distribution_id']
            Client().get_cloudfront().create_invalidation_request(
                distro_id, [filename])
        except KeyError:
            pass
        except CloudFrontServerError as e:
            if e.error_code == 'TooManyInvalidationsInProgress':
                self.retry(exc=e)
            else:
                raise
Esempio n. 18
0
def show_image(request_format, image_id, size):
    session = Client().session()
    image = session.query(Image).\
        filter(Image.image_id == image_id).\
        one()
    if g.user:
        albums = session.query(Album).all()
    else:
        albums = []
    try:
        album = filter(lambda a: a.album_id == image.album_id, albums)[0]
    except IndexError:
        album = None
    resizes = session.query(ImageResize).\
        filter(ImageResize.image_id == image_id).\
        order_by(ImageResize.width.asc()).\
        all()
    url = ImageTruck.url_for_filename(image.filename)
    if resizes and size != 'original':
        if size not in map(lambda r: r.suffix, resizes):
            size = resizes[0].suffix
        url = '%s_%s' % (url, size)
    tags = image.get_tags()
    if request_format == 'html':
        return render_template('image.html.jinja',
                               image=image,
                               album=album,
                               albums=albums,
                               url=url,
                               tags=tags,
                               resizes=resizes,
                               user=g.user,
                               size=size)
    elif request_format == 'json':
        return {
            'description': image.description,
            'title': image.title,
            'camera': image.camera,
            'photographed_at': image.photographed_at,
            'focal_length': image.focal_length,
            'aperture': image.aperture,
            'shutter_speed': image.shutter_speed,
            'iso': image.iso,
            'album_id': image.album_id,
            'tags': list(tags),
            'source_url': url,
        }
Esempio n. 19
0
    def test_add_an_album(self):
        response = self.app.post('/new_album', data={'name': 'my pics'})
        eq_(response.status_code, 302, response.data)
        eq_(response.headers['Location'], 'http://localhost/add')

        session = Client().session()
        albums = session.query(Album.name).all()
        eq_(albums, [('my pics',)])
Esempio n. 20
0
    def test_creating_with_a_new_source_url_updates_existing_record(self):
        session = Client().session()
        session.add(Image(filename='badcafe', source_url='example.com'))
        session.flush()
        session.add(Image(filename='badcafe', source_url='examp.le'))
        session.flush()

        source_url = session.query(Image.source_url).first()
        eq_(source_url, ('examp.le',))
Esempio n. 21
0
 def wrapper(self, transaction_id, *args, **kwargs):
     session = Client().session()
     transactions_found = session.query(TaskTransaction).\
         filter(TaskTransaction.transaction_id == transaction_id).\
         delete()
     if transactions_found == 0:
         raise self.retry()
     else:
         return task(self, *args, **kwargs)
Esempio n. 22
0
    def test_upload_several_images_in_one_go(self, ImageTruck, delay):
        (truck1, truck2, truck3) = (Mock(), Mock(), Mock())

        truck1.filename = 'BAD1DEA'
        truck1.url.return_value = 'cloudfrunt.nut/BAD1DEA'
        truck1.contents = b'boom'
        truck1.content_type = "image/jpeg"

        truck2.filename = 'CAFEBABE'
        truck2.url.return_value = 'cloudfrunt.nut/CAFEBABE'
        truck2.contents = b'shaka'
        truck2.content_type = "image/jpeg"

        truck3.filename = 'DADD1E'
        truck3.url.return_value = 'cloudfrunt.nut/DADD1E'
        truck3.contents = b'laka'
        truck3.content_type = "image/jpeg"

        ImageTruck.new_from_stream.side_effect = [truck1, truck2, truck3]

        id1 = str(uuid.uuid4())
        id2 = str(uuid.uuid4())
        id3 = str(uuid.uuid4())
        delay.side_effect = [id1, id2, id3]

        response = self.app.post('/add.json', data={
            'album': '',
            'url': '',
            'file[]': [
                (StringIO(str('boom')), 'image_1.jpg'),
                (StringIO(str('shaka')), 'image_2.jpg'),
                (StringIO(str('laka')), 'image_3.jpg'),
            ]})
        eq_(response.status_code, 200, response.data)

        session = Client().session()
        images = session.query(Image).all()
        body = json.loads(response.data)

        eq_(body, [
            {
                'url': 'cloudfrunt.nut/BAD1DEA',
                'image_id': images[0].image_id,
                'task_id': id1,
            },
            {
                'url': 'cloudfrunt.nut/CAFEBABE',
                'image_id': images[1].image_id,
                'task_id': id2,
            },
            {
                'url': 'cloudfrunt.nut/DADD1E',
                'image_id': images[2].image_id,
                'task_id': id3,
            },
        ])
Esempio n. 23
0
    def images_for_album_id(cls, album_id):
        from catsnap.table.image import Image

        session = Client().session()
        return (
            session.query(Image)
            .filter(Image.album_id == album_id)
            .order_by(coalesce(Image.photographed_at, Image.created_at))
            .all()
        )
Esempio n. 24
0
 def remove_tag(self, tag_name):
     from catsnap.table.image_tag import ImageTag
     from catsnap.table.tag import Tag
     session = Client().session()
     image_tag = session.query(ImageTag).\
             join(Tag, Tag.tag_id == ImageTag.tag_id).\
             filter(Tag.name == tag_name).\
             filter(ImageTag.image_id == self.image_id).\
             one()
     session.delete(image_tag)
    def test_only_deletes_appropriate_transaction(self):
        raw_task = self.mock_task()
        task = worker.task(wait_for_transaction(raw_task), bind=True)
        transaction_id = TaskTransaction.new_id()
        other_transaction_id = TaskTransaction.new_id()
        task(transaction_id)

        session = Client().session()
        transaction_ids = session.query(TaskTransaction.transaction_id).all()
        eq_(transaction_ids, [(other_transaction_id,)])
Esempio n. 26
0
    def test_add_a_tag(self):
        session = Client().session()
        image = Image(filename='deadbeef')
        session.add(image)
        session.flush()

        response = self.app.patch('/image/%d.json' % image.image_id, data={
            'add_tag': 'cow',
        })
        eq_(response.status_code, 200)

        body = json.loads(response.data)
        eq_(body['status'], 'ok')

        tag = session.query(Tag).filter(Tag.name == 'cow').one()
        image_tag = session.query(ImageTag).\
                filter(ImageTag.tag_id == tag.tag_id).\
                one()
        eq_(image_tag.image_id, image.image_id)
Esempio n. 27
0
 def get_filenames(self):
     from catsnap.table.image import Image
     from catsnap.table.image_tag import ImageTag
     session = Client().session()
     filenames = session.query(Image.filename).\
             join(ImageTag).\
             filter(ImageTag.image_id == Image.image_id).\
             filter(ImageTag.tag_id == self.tag_id)
     for filename in filenames:
         yield filename[0]
Esempio n. 28
0
    def test_add_tags_creates_tag_row_if_necessary(self):
        session = Client().session()
        image = Image(filename='baba15')
        session.add(image)
        image.add_tags(['booya'])

        tag = session.query(Tag).\
                filter(Tag.name=='booya').\
                first()

        assert tag, 'no tag was created'
Esempio n. 29
0
 def get_tags(self):
     #whee circular references
     from catsnap.table.image_tag import ImageTag
     from catsnap.table.tag import Tag
     session = Client().session()
     tags = session.query(Tag.name).\
         join(ImageTag).\
         filter(ImageTag.image_id == self.image_id).\
         filter(ImageTag.tag_id == Tag.tag_id)
     for row in tags:
         yield row[0]
Esempio n. 30
0
    def test_tab_from_tag_input_focuses_next_tag_input_and_saves(self):
        self.upload_one_image()
        self.browser.click_link_by_text('Add tag')
        self.browser.find_by_name('tag').first.fill('chipmunk\t')
        # there is no .is_focused or anything, so we'll do it inside-out:
        # look for a focused input and assert that it's the right one.
        next_tag = self.browser.find_by_css('input:focus').first
        eq_(next_tag['name'], "tag", "wrong input was focused")

        session = Client().session()
        image = session.query(Image).one()
        eq_(list(image.get_tags()), ["chipmunk"])