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)
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)
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)
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,)])
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, [])
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)
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, }
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, }
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}
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}
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)
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')
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')
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"
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)
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)
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
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, }
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',)])
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',))
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)
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, }, ])
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() )
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,)])
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)
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]
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'
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]
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"])