示例#1
9
 def handle(self, *args, **options):
     checked = added = 0
     images = Image.objects.values_list("phash", flat=True)
     galleries = Gallery.objects.values_list("slug", flat=True)
     gallery_path = os.path.join(settings.MEDIA_ROOT, "gallery")
     for root, dirs, f in os.walk(gallery_path):
         for dir in dirs:
             if dir not in galleries:
                 gallery = Gallery(name=dir)
                 gallery.save()
             else:
                 gallery = Gallery.objects.get(slug=dir)
             for dir_root, d, files in os.walk(os.path.join(root, dir)):
                 for file in files:
                     file_name = os.path.join(dir_root, file)
                     file_image = PILImage.open(file_name)
                     file_phash = str(phash(file_image))
                     checked += 1
                     if file_phash not in images:
                         image = Image(phash=file_phash, gallery=gallery)
                         image.original_image.name = file_name.replace(
                             settings.MEDIA_ROOT, ""
                         )[1:]
                         image.save()
                         self.stdout.write("Saved %s" % image.original_image.name)
                         added += 1
     self.stdout.write("Checked %d images, added %d" % (checked, added))
示例#2
0
    def test_geocode_image_location_post(self):
        '''
        Test you can geocode image view
        '''

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)
        im.save()

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.post('/image={0}/address/'.format(im.id),
                                    {'address': 'Freddie Mercury Montreux'})

        im.delete_image_files()

        self.assertEqual(200, response.status_code)
        self.assertEqual(True, b'46.43' in response.content)
        self.assertEqual(True, b'6.9' in response.content)

        im = Image.objects.get(id=im.id)
        self.assertEqual(46.43, round(im.latitude, 2))
        self.assertEqual(6.9, round(im.longitude, 1))
示例#3
0
    def test_gallery_with_auto_open_image_loads(self):
        '''
        Tests that the gallery view loads when a photo to open by
        is specified
        '''

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)
        im.save()

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.get('/gallery={0}/image={1}/'.format(
            self.gallery.id, im.id))

        im.delete_image_files()

        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'gallery/gallery.html')
示例#4
0
    def _process_files(self, fs_filenames, root_object, root_phys_path):
        db_files = root_object.files.all()
        for file_object in db_files:
            if file_object.name not in fs_filenames:
                # if any of images under root doesn't exist -> remove it from db
                logger.info("scheduling file removal: " + file_object.path)
                self._removals.append(file_object)
            else:
                # update mtime if neeeded
                self._update_mtime_if_needed(file_object)

        # add file objects if not found on db
        db_filenames = {x.name for x in db_files}
        for missing_file in set(fs_filenames) - db_filenames:
            file_phys_path = os.path.join(root_phys_path, missing_file)
            file_mtime = get_mtime_datetime(file_phys_path)

            if is_jpeg(missing_file):
                aspect_ratio = self.get_image_aspect_ratio(file_phys_path)
                raw_filename = self._detect_rawfile(file_phys_path)
                file_object = Image(name=missing_file, directory=root_object, modification_time=file_mtime,
                                    aspect_ratio=aspect_ratio, raw_filename=raw_filename)
            elif is_video(missing_file):
                file_object = Video(name=missing_file, directory=root_object, modification_time=file_mtime)
            else:
                raise Exception("File should be either Image or Video" + missing_file)

            file_object.save()
            logger.info("adding file " + file_object.path)
示例#5
0
    def test_partial_update_remove_thumbnail(self):
        image = Image(gallery=self.gallery,
                      family=self.family,
                      original_image=''.join([
                          'galleries/',
                          str(self.family.id), '/',
                          str(self.gallery.id), '/test_image.jpg'
                      ]))
        image.save()

        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/gallery/{0}/'.format(self.gallery.id)

        data = {
            'thumbnail_id': '',
        }

        response = client.patch(url, data, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue('"thumbnail":null' in response.content.decode("utf-8"))
        json.loads(response.content)

        image.delete_local_image_files()
        image.delete_remote_image_files()
示例#6
0
文件: views.py 项目: GithubArs/ARS
def snap(request):
    if request.POST and request.is_ajax():
        image_data = b64decode(request.POST.get("image_data", ""))
        filename = id_generator() + '.png'
        fh = open(settings.TMP_ROOT + filename, "wb")
        fh.write(image_data)
        fh.close()
        image = getImage(settings.TMP_ROOT)
        path = settings.TMP_ROOT + image
        vClase, vScore = classifyScreenshot(path)

        db = Image(name=filename,
                   image=path,
                   clase=vClase,
                   score=vScore * 100,
                   retrain=0)
        db.save()

        vClasif = classRetrieve()

        record = {}
        data = serializers.serialize(
            "json", Time.objects.filter(name=vClase,
                                        date=datetime.date.today()))
        record = data
        print(record)

        return HttpResponse(json.dumps({
            'clase': vClase,
            'score': str(round((vScore * 100), 2)),
            'classif': vClasif,
            'record': record
        }),
                            content_type="application/json")
示例#7
0
    def test_rotate_image(self):
        '''
        Tests that user can rotate image succesffully
        '''
        p = Person.objects.create(name='badger', family_id=self.family.id)

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        im = Image(
                    gallery=self.gallery,
                    family=self.family,
                    original_image=self.test_image_key,
                    thumbnail=self.test_image_key,
                    large_thumbnail=self.test_image_key
                )
        im.save()
        im.upload_files_to_s3()

        tag = Tag(
                image_id=im.id,
                x1=0.5,
                y1=0.8,
                x2=0.5,
                y2=0.5,
                person_id=p.id)
        tag.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.post('/image={0}/rotate/'.format(im.id), {'anticlockwise_angle': '90'})

        self.assertNotEqual(404, response.status_code)

        tag = Tag.objects.get(id=tag.id)
        self.assertEqual(0.8, tag.x2)
示例#8
0
    def test_create_tag(self):
        '''
        Tests create tag api
        '''
        image = Image(gallery=self.gallery,
                      family=self.family,
                      original_image=self.test_image_destination,
                      thumbnail=self.test_image_destination,
                      large_thumbnail=self.test_image_destination)
        image.save()

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.post(
            '/image={0}/tags/create/'.format(self.image.id), {
                'person': self.person.id,
                'x1': 0.314159,
                'y1': 0.1,
                'x2': 0.6,
                'y2': 0.2,
            })

        self.assertEqual(200, response.status_code)
        tag = Tag.objects.get(x1=0.314159)
        self.assertEqual(self.person.id, tag.person_id)
        self.assertEqual(0.2, tag.y2)
示例#9
0
    def test_rotate_image_not_allowed_for_user_in_different_family(self):
        '''
        Tests that user can not rotate image for another family
        '''
        p = Person.objects.create(name='badger', family_id=self.family.id)

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)
        im.save()

        tag = Tag(image_id=im.id,
                  x1=0.5,
                  y1=0.8,
                  x2=0.5,
                  y2=0.5,
                  person_id=p.id)
        tag.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.post('/image={0}/rotate/'.format(im.id),
                                    {'anticlockwise_angle': '90'})

        self.assertEqual(404, response.status_code)

        tag = Tag.objects.get(id=tag.id)
        self.assertEqual(0.5, tag.x2)
示例#10
0
    def test_save_image(self):
        im = Image()
        im.image_name = "home"
        im.image_url = File(open("/tmp/uplods/home.jpg"))
        im.save()

        h_image = im.objects.get(id=1).image_url.path
        self.failUnless(open(h_image), "file not found")
示例#11
0
def add_images(request, id):
    gallery = get_object_or_404(Service, id=id, deleted=False)
    data = {'gallery': gallery}
    if request.method == 'POST':
        images = request.FILES
        new = Image(name=images['file'], service=gallery)
        new.save()
        messages.success(request, 'Imágenes subidas satisfactoriamente.')
    return render_to_response('galleries/add_images.html', {'data': data}, RequestContext(request))
示例#12
0
    def create(self, request):
        '''
        Image upload
        '''
        queryset = Gallery.objects.filter(family_id=request.user.family_id)
        gallery_id, gallery_id_valid = intTryParse(
            request.data.get("gallery_id"))

        if not gallery_id_valid:
            raise ParseError('Invalid gallery_id')

        # Check gallery is part of family
        gallery = get_object_or_404(queryset, pk=gallery_id)

        try:
            uploaded = request.FILES['picture']
            name, ext = os.path.splitext(uploaded.name)

            if uploaded.size > MAX_FILE_SIZE:
                raise ParseError('File too big')

            filename = create_hash(uploaded.name) + '.jpg'
            image = Image(gallery_id=gallery.id,
                          family_id=gallery.family_id,
                          title=name,
                          uploaded_by=request.user)

            path = upload_to(image, filename)

            #Write the file to the destination
            destination = open(os.path.join(settings.MEDIA_ROOT, path), 'wb+')

            for chunk in uploaded.chunks():
                destination.write(chunk)
            destination.close()

            image.original_image = path
            PIL.Image.open(
                os.path.join(settings.MEDIA_ROOT,
                             str(image.original_image))).verify()
            image.save()

            image.upload_files_to_s3()
            image.delete_local_image_files()

            create_message('image_face_detect', image.id)

            serializer = ImageSerializer(image)
            return Response(serializer.data)

        except Exception as e:

            if image:
                image.delete_local_image_files()
                image.delete()

            raise ParseError(str(e))
示例#13
0
def AddImage(request):
    if request.method == 'POST':
        form = AddImageForm(request.POST, request.FILES)
        if form.is_valid():
            i=Image(title=form.cleaned_data['title'], desc=form.cleaned_data['desc'], file=form.cleaned_data['file'])
            i.save()
            return HttpResponseRedirect('/')
    else:
        form=AddImageForm()

    return render_to_response('form.html', {'form': form, })
示例#14
0
def uploadImage(request):
    if request.method == 'POST':
        # images = request.FILES.getlist('images')
        images = request.FILES.getlist(
            'files[]')  # ssi-uploader插件返回的数据Key=files[]
        print(images)
        for image in images:
            new_img = Image(img=image)
            new_img.save()
        return HttpResponse("1")
    else:
        return render(request, 'gallery/upload.html')
示例#15
0
    def test_image_detail_view_does_not_load_for_another_family(self):
        '''
        Test that the image detail view loads
        '''
        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)
        im.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.get('/image={0}/details/'.format(im.id))

        self.assertEqual(404, response.status_code)
示例#16
0
    def test_image_delete_another_family(self):
        '''
        Tests that you can't delete another family's image
        '''
        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)
        im.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.post('/image={0}/delete/'.format(im.id))

        self.assertEqual(404, response.status_code)
示例#17
0
    def test_partial_update(self):
        shutil.copy2(self.test_image, self.test_image_destination)

        image = Image(gallery=self.gallery,
                      family=self.family,
                      original_image=''.join([
                          'galleries/',
                          str(self.family.id), '/',
                          str(self.gallery.id), '/test_image.jpg'
                      ]))
        image.save()

        image2 = Image(gallery=self.gallery,
                       family=self.family,
                       original_image=''.join([
                           'galleries/',
                           str(self.family.id), '/',
                           str(self.gallery.id), '/test_image.jpg'
                       ]))
        image2.save()

        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/gallery/{0}/'.format(self.gallery.id)

        data = {
            'family_id': self.family2.id,  # try to switch families
            'title': 'new title',
            'description': 'new description',
            'thumbnail_id': image2.id,
        }

        response = client.patch(url, data, format='json')

        gallery = Gallery.objects.get(id=self.gallery.id)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual('new title', gallery.title)
        self.assertEqual(self.family.id, gallery.family_id)
        self.assertTrue(b'new title' in response.content)
        self.assertTrue(b'new description' in response.content)
        self.assertTrue(
            str(image2.thumbnail) in response.content.decode("utf-8"))

        image.delete_local_image_files()
        image.delete_remote_image_files()
        image2.delete_local_image_files()
        image2.delete_remote_image_files()
class TagTestCase(TestCase): # pragma: no cover
    '''
    Tests for the image class
    '''

    def setUp(self):
        '''
        Need to create a family and a gallery and image
        '''
        self.family = Family()
        self.family.save()

        self.person = Person(name='Wallace', gender='M', email='*****@*****.**', family_id=self.family.id, language='en')
        self.person.save()

        self.gallery = Gallery.objects.create(title="test_gallery", family_id=self.family.id)

        self.test_image = os.path.join(settings.BASE_DIR, 'gallery/tests/test_image.jpg')
        self.test_image_destination = ''.join([settings.MEDIA_ROOT, 'galleries/', str(self.family.id), '/', str(self.gallery.id), '/test_image.jpg'])

        directory = ''.join([settings.MEDIA_ROOT, 'galleries/', str(self.family.id), '/', str(self.gallery.id)])
        if not os.path.exists(directory):
            os.makedirs(directory)

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        self.image = Image(gallery=self.gallery, family=self.family, original_image=''.join(['galleries/', str(self.family.id), '/', str(self.gallery.id), '/test_image.jpg']))
        self.image.save()


    def test_rotate_tag(self):
        '''
        Tests that we can rotate a tag correctly
        '''
        tag = Tag.objects.create(image_id=self.image.id, x1=0.1, y1=0.2, x2=0.3, y2=0.4, person_id=self.person.id)
        tag.rotate(90)

        #print(tag.x1)
        self.assertTrue(abs(0.2 - tag.x1) < 0.0001)
        #print(tag.y1)
        self.assertTrue(abs(0.7 - tag.y1) < 0.0001)
        #print(tag.x2)
        self.assertTrue(abs(0.4 - tag.x2) < 0.0001)
        #print(tag.y2)
        self.assertTrue(abs(0.9 - tag.y2) < 0.0001)
示例#19
0
    def test_image_delete(self):
        '''
        Tests that you can delete an image through api
        '''
        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)
        im.save()

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.post('/image={0}/delete/'.format(im.id))

        self.assertEqual(302, response.status_code)
        self.assertEqual(0, Image.objects.filter(id=im.id).count())
示例#20
0
def process_image(filename, file, gallery):
    '''
    Processes each image file
    '''
    name, ext = os.path.splitext(file.name)
    filename =  create_hash(name) +'.jpg'

    im = Image(gallery_id=gallery.id, family_id=gallery.family_id, title=name)
    upload_name = upload_to(im, filename)

    result = {
        'name': basename(name),
        'size': file.size,
        'url': settings.MEDIA_URL + str(upload_name),
        'filename': filename
    }

    if file.size > MAX_FILE_SIZE:
        result['error'] = tran('File is too big')
        return result

    #Write the file to the destination
    destination = open(os.path.join(settings.MEDIA_ROOT, str(upload_name)), 'wb+')

    for chunk in file.chunks():
        destination.write(chunk)
    destination.close()

    im.original_image = upload_name

    #Check this is a valid image
    try:
        PIL.Image.open(os.path.join(settings.MEDIA_ROOT, str(im.original_image))).verify()
        im.save()
        im.upload_files_to_s3()
        im.delete_local_image_files()

        result['image_id'] = im.id


    except:
        im.delete_local_image_files()
        result['error'] = tran('Invalid image!')

    return result
    def test_save_and_rotate_image(self):
        '''
        Tests that we can save an image and rotate it without error
        '''

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        image = Image(gallery=self.gallery,
                      family=self.family,
                      original_image=''.join([
                          'galleries/',
                          str(self.family.id), '/',
                          str(self.gallery.id), '/test_image.jpg'
                      ]))
        image.save()

        image.rotate(90)
示例#22
0
    def test_make_image_gallery_thumbnail(self):
        '''
        Tests that you can assign a thumbnail to a gallery
        '''
        im = Image(
                    gallery=self.gallery,
                    family=self.family,
                    original_image=self.test_image_destination,
                    thumbnail=self.test_image_destination,
                    large_thumbnail=self.test_image_destination
                )
        im.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.post('/image={0}/make_gallery_thumbnail/'.format(im.id))

        self.assertEqual(302, response.status_code)
        self.assertEqual(im.thumbnail, Gallery.objects.get(id=self.gallery.id).thumbnail)
示例#23
0
    def test_image_detail_view_loads(self):
        '''
        Test that the image detail view loads
        '''
        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)

        im.save()

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.get('/image={0}/details/'.format(im.id))

        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'gallery/image_tagging.html')
示例#24
0
    def test_image_detail_update_does_not_update_for_non_whitelisted_field(self):
        '''
        Tests that you can update a field on the image using api
        '''
        im = Image(
                    gallery=self.gallery,
                    family=self.family,
                    original_image=self.test_image_destination,
                    thumbnail=self.test_image_destination,
                    large_thumbnail=self.test_image_destination,
                    title='innuendo'

                )
        im.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.post('/image={0}/update/'.format(im.id), {'pk': im.id, 'name': 'id', 'value': 1})

        self.assertEqual(404, response.status_code)
示例#25
0
    def process_image(self, image_data):
        """
        Takes the dictionary representing an image and saves it to an instance of
        the gallery.Image model.
        """
        author_name = image_data['account_url']
        if author_name:
            new = Image()
            new.title = image_data['title']
            new.size = image_data['size']
            new.hash = image_data['hash']
            new.ext = image_data['ext']

            # TODO: make sure all these methods are implemented correctly
            new.author = self.get_or_create_author(author_name)
            new.timestamp = self.parse_datetime(image_data['timestamp'])
            new.build_urls()
            new.save()
        else:
            print "Image %(hash)s didn't have an author" % image_data
示例#26
0
文件: views.py 项目: aribfp/ars
def snap(request):
  if request.POST and request.is_ajax():  
    image_data = b64decode(request.POST.get("image_data", ""))
    filename = id_generator()+'.png'
    fh = open(settings.TMP_ROOT + filename, "wb")
    fh.write(image_data)
    fh.close();
    image = getImage(settings.TMP_ROOT)
    path = settings.TMP_ROOT + image
    vClase, vScore = classifyScreenshot(path)

    db = Image(name=filename, 
            image=path,
            clase=vClase,
            score=vScore * 100,
            retrain=0);
    db.save();

    vClasif = classRetrieve()
    return HttpResponse(json.dumps({ 'clase':vClase ,'score': str(round((vScore * 100), 2)), 'classif':vClasif }), content_type="application/json")
示例#27
0
    def test_image_face_detect(self):

        # Upload new image
        new_test_image = os.path.join(
            settings.BASE_DIR,
            'facial_recognition/tests/test_image_woman_and_baby.jpg')
        new_test_image_destination = ''.join([
            settings.MEDIA_ROOT, 'galleries/',
            str(self.family.id), '/',
            str(self.gallery.id), '/test_image_woman_and_baby.jpg'
        ])

        # Copy to test area
        shutil.copy2(new_test_image, new_test_image_destination)

        new_image = Image(gallery=self.gallery,
                          family=self.family,
                          original_image=''.join([
                              'galleries/',
                              str(self.family.id), '/',
                              str(self.gallery.id),
                              '/test_image_woman_and_baby.jpg'
                          ]))
        new_image.save()
        new_image.upload_files_to_s3()

        # Create a message to resize tag
        image_face_detect_queue_id = Queue.objects.get(
            name='image_face_detect').id
        message = Message.objects.create(queue_id=image_face_detect_queue_id,
                                         integer_data=new_image.id)

        image_face_detect([message])

        suggested_tags = SuggestedTag.objects.filter(image_id=new_image.id)

        self.assertEqual(2, suggested_tags.count())
        self.assertEqual(self.person.id, suggested_tags[0].person_id)

        new_image.delete_local_image_files()
        new_image.delete_remote_image_files()
示例#28
0
    def test_image_detail_update(self):
        '''
        Tests that you can update a field on the image using api
        '''
        im = Image(
                    gallery=self.gallery,
                    family=self.family,
                    original_image=self.test_image_destination,
                    thumbnail=self.test_image_destination,
                    large_thumbnail=self.test_image_destination
                )
        im.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.post('/image={0}/update/'.format(im.id), {'pk': im.id, 'name': 'title', 'value': 'the show must go on'})

        #Reload image
        im = Image.objects.get(id=im.id)

        self.assertEqual(200, response.status_code)
        self.assertEqual('the show must go on', im.title)
示例#29
0
    def process_image(self, image_data):
        """
        Takes the dictionary representing an image and saves it to an instance of
        the gallery.Image model.
        """
        author_name = image_data['account_url']
        if author_name:
            new = Image()
            new.title = image_data['title']
            new.size = image_data['size']
            new.hash = image_data['hash']
            new.ext = image_data['ext']

            # TODO: make sure all these methods are implemented correctly
            new.author = self.get_or_create_author(author_name)
            new.timestamp = self.parse_datetime(image_data['timestamp'])
            new.build_urls(hash)
            new.save()
            /* TO SAVE THE FILES IN DOWNLOADS FOLDER */
           filename_charset = string.ascii_letters + string.digits
           file_save_dir = MEDIA_ROOT
           urllib.urlretrieve ("http://i.imgur.com/"+(new.hash),os.path.join(file_save_dir, (new.hash) + '.jpg'))
示例#30
0
    def test_geocode_image_location_post_other_family(self):
        '''
        Test another family cannot geocode image
        '''

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        im = Image(gallery=self.gallery,
                   family=self.family,
                   original_image=self.test_image_destination,
                   thumbnail=self.test_image_destination,
                   large_thumbnail=self.test_image_destination)
        im.save()

        self.client.login(email='*****@*****.**', password='******')
        response = self.client.post('/image={0}/address/'.format(im.id),
                                    {'address': 'Freddie Mercury Montreux'})

        im.delete_image_files()

        self.assertEqual(404, response.status_code)
示例#31
0
    def test_delete_tag_fails_for_different_family(self):
        '''
        Tests tag deletion api
        '''
        image = Image(gallery=self.gallery,
                      family=self.family,
                      original_image=self.test_image_destination,
                      thumbnail=self.test_image_destination,
                      large_thumbnail=self.test_image_destination)
        image.save()
        tag = Tag.objects.create(image=image,
                                 person=self.person,
                                 x1=1,
                                 x2=2,
                                 y1=3,
                                 y2=4)

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.post('/tag={0}/delete/'.format(tag.id))

        self.assertEqual(404, response.status_code)
示例#32
0
    def test_delete_tag(self):
        '''
        Tests tag deletion api
        '''
        image = Image(gallery=self.gallery,
                      family=self.family,
                      original_image=self.test_image_destination,
                      thumbnail=self.test_image_destination,
                      large_thumbnail=self.test_image_destination)
        image.save()
        tag = Tag.objects.create(image=image,
                                 person=self.person,
                                 x1=1,
                                 x2=2,
                                 y1=3,
                                 y2=4)

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.post('/tag={0}/delete/'.format(tag.id))

        self.assertEqual(200, response.status_code)
        self.assertEqual(0, Tag.objects.filter(id=tag.id).count())
示例#33
0
    def test_create_tag_fails_for_another_family(self):
        '''
        Tests create tag api fails if in wrong family
        '''
        image = Image(gallery=self.gallery,
                      family=self.family,
                      original_image=self.test_image_destination,
                      thumbnail=self.test_image_destination,
                      large_thumbnail=self.test_image_destination)
        image.save()

        self.client.login(email='*****@*****.**',
                          password='******')
        response = self.client.post(
            '/image={0}/tags/create/'.format(self.image.id), {
                'person': self.person.id,
                'x1': 0.314159,
                'y1': 0.1,
                'x2': 0.6,
                'y2': 0.2,
            })

        self.assertEqual(404, response.status_code)
示例#34
0
class ImageApiTestCase(TestCase):
    '''
    Tests for the Image API
    '''
    def setUp(self):

        self.family = Family()
        self.family.save()

        self.user = User.objects.create_user(email='*****@*****.**',
                                             password='******',
                                             name='Phil Collins',
                                             family=self.family)

        self.person = Person(name='Phil Collins',
                             gender='M',
                             email='*****@*****.**',
                             family_id=self.family.id,
                             language='en',
                             user_id=self.user.id)
        self.person.save()

        self.gallery = Gallery.objects.create(title="test_gallery",
                                              family_id=self.family.id)
        self.test_image = os.path.join(settings.BASE_DIR,
                                       'gallery/tests/test_image.jpg')
        self.test_image_destination = ''.join([
            settings.MEDIA_ROOT, 'galleries/',
            str(self.family.id), '/',
            str(self.gallery.id), '/test_image.jpg'
        ])

        directory = ''.join([
            settings.MEDIA_ROOT, 'galleries/',
            str(self.family.id), '/',
            str(self.gallery.id)
        ])
        if not os.path.exists(directory):
            os.makedirs(directory)

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        self.image = Image(gallery=self.gallery,
                           family=self.family,
                           original_image=''.join([
                               'galleries/',
                               str(self.family.id), '/',
                               str(self.gallery.id), '/test_image.jpg'
                           ]))
        self.image.save()

        #Tag person 1 in image
        self.tag = Tag.objects.create(image=self.image,
                                      person=self.person,
                                      x1=1,
                                      x2=2,
                                      y1=3,
                                      y2=4)

        self.gallery2 = Gallery.objects.create(title="test_gallery2",
                                               family_id=self.family.id)
        self.test_image2 = os.path.join(settings.BASE_DIR,
                                        'gallery/tests/test_image.jpg')
        self.test_image2_destination = ''.join([
            settings.MEDIA_ROOT, 'galleries/',
            str(self.family.id), '/',
            str(self.gallery2.id), '/test_image.jpg'
        ])

        directory = ''.join([
            settings.MEDIA_ROOT, 'galleries/',
            str(self.family.id), '/',
            str(self.gallery2.id)
        ])
        if not os.path.exists(directory):
            os.makedirs(directory)

        #Copy test image to media area
        shutil.copy2(self.test_image2, self.test_image2_destination)

        self.image2 = Image(gallery=self.gallery2,
                            family=self.family,
                            original_image=''.join([
                                'galleries/',
                                str(self.family.id), '/',
                                str(self.gallery2.id), '/test_image.jpg'
                            ]))
        self.image2.save()

        self.family2 = Family()
        self.family2.save()

        self.user2 = User.objects.create_user(
            email='*****@*****.**',
            password='******',
            name='Phillip Bailey',
            family=self.family2)

        self.person2 = Person(name='Phillip Bailey',
                              gender='M',
                              email='*****@*****.**',
                              family_id=self.family2.id,
                              language='en',
                              user_id=self.user2.id)
        self.person2.save()

        super(ImageApiTestCase, self).setUp()

    def tearDown(self):
        self.image.delete_local_image_files()
        threading.Thread(target=self.image.delete_remote_image_files).start()
        self.image2.delete_local_image_files()
        threading.Thread(target=self.image2.delete_remote_image_files).start()

        # Delete any updates
        try:
            self.image = Image.objects.get(id=self.image.id)
            self.image.delete_local_image_files()
            threading.Thread(
                target=self.image.delete_remote_image_files).start()
        except:
            pass

        try:
            self.image2 = Image.objects.get(id=self.image2.id)
            self.image2.delete_local_image_files()
            threading.Thread(
                target=self.image2.delete_remote_image_files).start()
        except:
            pass

        try:
            os.remove(self.test_image_destination)
        except:
            pass

        try:
            os.remove(self.test_image2_destination)
        except:
            pass

    def test_list_requires_authentication(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        response = client.get('/api/image/?page=1', format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        json.loads(response.content)

    def test_list_page1(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')

        # Check this works with JWT token
        auth_details = {
            'email': '*****@*****.**',
            'password': '******'
        }
        auth_response = client.post('/api/auth/obtain_token/',
                                    auth_details,
                                    format='json')
        token = json.loads(auth_response.content)["access"]

        client.credentials(HTTP_AUTHORIZATION='Bearer ' + token)
        response = client.get('/api/image/?page=1', format='json')

        # Check it contains both images
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(str(self.image.thumbnail).encode() in response.content)
        self.assertTrue(
            str(self.image2.thumbnail).encode() in response.content)
        json.loads(response.content)

    def test_list_page1_other_family(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')

        # Login with other user
        auth_details = {
            'email': '*****@*****.**',
            'password': '******'
        }
        auth_response = client.post('/api/auth/obtain_token/',
                                    auth_details,
                                    format='json')
        token = json.loads(auth_response.content)["access"]

        client.credentials(HTTP_AUTHORIZATION='Bearer ' + token)
        response = client.get('/api/image/?page=1', format='json')

        # Check it contains neither images
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertFalse(
            str(self.image.thumbnail).encode() in response.content)
        self.assertFalse(
            str(self.image2.thumbnail).encode() in response.content)
        json.loads(response.content)

    def test_list_by_gallery(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/image/?gallery_id={0}'.format(self.gallery2.id)
        response = client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertFalse(
            str(self.image.thumbnail).encode() in response.content)
        self.assertTrue(
            str(self.image2.thumbnail).encode() in response.content)
        json.loads(response.content)

    def test_list_by_tagged_person(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/image/?person_id={0}'.format(self.person.id)
        response = client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(str(self.image.thumbnail).encode() in response.content)
        self.assertFalse(
            str(self.image2.thumbnail).encode() in response.content)
        json.loads(response.content)

    def test_retrieve_requires_authentication(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        url = '/api/image/{0}/'.format(self.image.id)
        response = client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        json.loads(response.content)

        os.remove(self.test_image_destination)
        os.remove(self.test_image2_destination)

    def test_retrieve(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/image/{0}/'.format(self.image.id)
        response = client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(str(self.image.thumbnail).encode() in response.content)
        json.loads(response.content)

    def test_retrieve_other_family(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user2)
        url = '/api/image/{0}/'.format(self.image.id)
        response = client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        json.loads(response.content)

    def test_create(self):
        '''
        test that we can upload a file
        '''
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)

        url = '/api/image/'
        with open(self.test_image, 'rb') as fp:

            data = {
                'picture': fp,
                'gallery_id': self.gallery.id,
            }

            response = client.post(url, data)

        # Check image loads
        image_id = json.loads(response.content)['id']
        image = Image.objects.get(id=image_id)

        image.delete_local_image_files()
        image.delete_remote_image_files()

        self.assertEqual(200, response.status_code)
        self.assertEqual('test_image', image.title)
        self.assertTrue('Phil Collins', image.uploaded_by.name)
        json.loads(response.content)

    def test_create_requires_authentication(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        url = '/api/image/'
        with open(self.test_image, 'rb') as fp:

            data = {
                'picture': fp,
                'gallery_id': self.gallery.id,
            }

            response = client.post(url, data)
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        json.loads(response.content)

    def test_create_other_family(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user2)
        url = '/api/image/'
        with open(self.test_image, 'rb') as fp:

            data = {
                'picture': fp,
                'gallery_id': self.gallery.id,
            }

            response = client.post(url, data)
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        json.loads(response.content)

    def test_destroy(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/image/{0}/'.format(self.image.id)
        response = client.delete(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        count = Image.objects.filter(id=self.image.id).count()
        self.assertEqual(0, count)
        json.loads(response.content)

    def test_destroy_requires_authentication(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        url = '/api/image/{0}/'.format(self.image.id)
        response = client.delete(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        json.loads(response.content)

    def test_destroy_other_family(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user2)
        url = '/api/image/{0}/'.format(self.image.id)
        response = client.delete(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        json.loads(response.content)

    def test_partial_update(self):
        self.image.upload_files_to_s3()

        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/image/{0}/'.format(self.image.id)

        data = {
            'title': 'new title',
            'description': 'new description',
            'anticlockwise_angle': 90,
            'latitude': 10,
            'longitude': 20,
        }

        response = client.patch(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(b'new title' in response.content)
        self.assertTrue(b'new description' in response.content)
        self.assertTrue(b'10' in response.content)
        self.assertTrue(b'20' in response.content)
        json.loads(response.content)

    def test_partial_update_requires_authentication(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        url = '/api/image/{0}/'.format(self.image.id)

        data = {
            'title': 'new title',
            'description': 'new description',
            'anticlockwise_angle': 90,
            'latitude': 10,
            'longitude': 20,
        }

        response = client.patch(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        json.loads(response.content)

    def test_partial_update_other_family(self):
        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user2)
        url = '/api/image/{0}/'.format(self.image.id)

        data = {
            'title': 'new title',
            'description': 'new description',
            'anticlockwise_angle': 90,
            'latitude': 10,
            'longitude': 20,
        }

        response = client.patch(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        json.loads(response.content)

    def test_partial_update_invalid_title(self):
        self.image.upload_files_to_s3()

        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/image/{0}/'.format(self.image.id)

        data = {
            'title': '    ',
            'description': 'new description',
            'anticlockwise_angle': 90,
            'latitude': 10,
            'longitude': 20,
        }

        response = client.patch(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        json.loads(response.content)

    def test_partial_update_optional_data_missing(self):
        self.image.upload_files_to_s3()

        client = APIClient(HTTP_X_REAL_IP='127.0.0.1')
        client.force_authenticate(user=self.user)
        url = '/api/image/{0}/'.format(self.image.id)

        data = {
            'title': 'new title',
            'description': 'new description',
        }

        response = client.patch(url, data, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(b'new title' in response.content)
        self.assertTrue(b'new description' in response.content)
        self.assertTrue(b'"longitude":0.0' in response.content)
        self.assertTrue(b'"latitude":0.0' in response.content)
        json.loads(response.content)
示例#35
0
class ResizeTagsTestCase(TestCase):  # pragma: no cover
    def setUp(self):
        '''
        Need to create a family and a gallery
        '''
        self.family = Family()
        self.family.save()

        self.gallery = Gallery.objects.create(title="test_gallery",
                                              family_id=self.family.id)

        self.test_image = os.path.join(
            settings.BASE_DIR, 'facial_recognition/tests/test_image_woman.jpg')
        self.test_image_destination = ''.join([
            settings.MEDIA_ROOT, 'galleries/',
            str(self.family.id), '/',
            str(self.gallery.id), '/test_image.jpg'
        ])
        self.test_image_s3_key = ''.join([
            'galleries/',
            str(self.family.id), '/',
            str(self.gallery.id), '/test_image.jpg'
        ])

        directory = ''.join([
            settings.MEDIA_ROOT, 'galleries/',
            str(self.family.id), '/',
            str(self.gallery.id)
        ])
        if not os.path.exists(directory):
            os.makedirs(directory)

        #Copy test image to media area
        shutil.copy2(self.test_image, self.test_image_destination)

        self.image = Image(gallery=self.gallery,
                           family=self.family,
                           original_image=''.join([
                               'galleries/',
                               str(self.family.id), '/',
                               str(self.gallery.id), '/test_image.jpg'
                           ]))
        self.image.save()
        self.image.upload_files_to_s3()

        self.person = Person(name='Wallace',
                             gender='M',
                             email='*****@*****.**',
                             family_id=self.family.id,
                             language='en')
        self.person.save()

        self.tag = Tag.objects.create(image_id=self.image.id,
                                      x1=0.3,
                                      y1=0.2,
                                      x2=0.5,
                                      y2=0.4,
                                      person_id=self.person.id)

    def test_tag_resizes(self):

        # Create a message to resize tag
        resize_tag_queue_id = Queue.objects.get(name='resize_tag').id
        message = Message.objects.create(queue_id=resize_tag_queue_id,
                                         integer_data=self.tag.id)

        resize_tags([message])

        resized_tag = Tag.objects.get(pk=self.tag.id)

        self.assertTrue(abs(0.279 - resized_tag.x1) < 0.001)
        self.assertTrue(abs(0.188 - resized_tag.y1) < 0.001)
        self.assertTrue(abs(0.536 - resized_tag.x2) < 0.001)
        self.assertTrue(abs(0.381 - resized_tag.y2) < 0.001)

        #Clear up
        self.image.delete_local_image_files()
        self.image.delete_remote_image_files()
示例#36
0
def post_edit_view(request, id):
    # Es obligatorio estar loguerdo
    if not request.user.is_authenticated:
        messages.error(request, 'Es necesario estar autenticado para editar posts')
        return redirect('blog:index')

    # Es obligatorio ser editor para tocar un post
    if not request.user.userprofile.author:
        messages.error(request, u'No está autorizado para editar posts')
        return redirect('blog:index')

    # Se obtiene el post a editar y si no existe se redirige al index
    try:
        post = Post.objects.get(id=id)
    except ObjectDoesNotExist:
        messages.error(request, 'El post indicado no existe')
        return redirect('blog:index')
    
    # Sólo se pueden editar posts propios
    if request.user != post.author.user:
        messages.error(request, u'Sólo pueden editarse los posts propios')
        return redirect('blog:index')

    # Si llega hasta aquí se puede continuar
    form = PostFormEdit(request.POST or None, request.FILES or None, instance=post)
    if request.method == 'POST':
        # Está correcta la información del form?
        if form.is_valid():
            status_old = post.status
            post = form.save(commit=False)
            post.slug = slugify(post.title)
            # Sólo si se selecciona una nueva imagen de cabecera se borra la antigua y se asigna la nueva
            if form.cleaned_data['image_file']:
                post.image.delete()
                image = Image()
                image.caption = form.cleaned_data['image_file'].name
                image.image = form.cleaned_data['image_file']
                image.post_slug = post.id
                image.save()
                post.image = image
            # Se graban los cambios del post, para poder seguir con el resto de datos
            post.save()
            post.add_log(request.user, "edit")
            # Si ha pasado a status publicado en este momento se actualizan los contadores del archivo
            if status_old != 'PB' and post.status == 'PB':
                try:
                    post_archive = PostArchive.objects.get(year=post.published_date.year, month=post.published_date.month)
                    post_archive.posts += 1
                    post_archive.save(force_update=True)
                except ObjectDoesNotExist:
                    post_archive = PostArchive()
                    post_archive.year = post.published_date.year
                    post_archive.month = post.published_date.month
                    post_archive.posts = 1
                    post_archive.save()
            # Se borran las categorías a las que estuviese asignado el post antteriormente y se crean y asocian
            # las nuevas categorías asignadas al post al editarlo
            for postC in PostCategory.objects.filter(post=post):
                postC.delete()
            for category in form.cleaned_data['postcategory']:
                post_category = PostCategory()
                post_category.post = post
                post_category.category = apps.get_model('category', 'Category').objects.get(id=category)
                post_category.save()
            # Sólo si se han asignado nuevas imagenes al post se borran las antiguas y se asignan las nuevas
            if len(form.cleaned_data['postimage']) > 0:
                for image in PostImage.objects.filter(post=post):
                    image.delete()
                for file_image in form.cleaned_data['postimage']:
                    image = Image()
                    image.caption = file_image.name
                    image.image = file_image
                    image.post_slug = post.id
                    image.save()
                    post_image = PostImage()
                    post_image.post = post
                    post_image.image = image
                    post_image.save()
            # Sólo si se han asignado nuevasss imagenes small al post se borran las antiguas y se asignan las nuevas
            if len(form.cleaned_data['postimagesmall']) > 0:
                for image_sm in PostImageSmall.objects.filter(post=post):
                    image_sm.delete()
                for file_image_sm in form.cleaned_data['postimagesmall']:
                    image_sm = Image()
                    image_sm.caption = file_image_sm.name
                    image_sm.image = file_image_sm
                    image_sm.post_slug = post.id
                    image_sm.save()
                    post_image_sm = PostImageSmall()
                    post_image_sm.post = post
                    post_image_sm.image = image_sm
                    post_image_sm.save()
            # Datos grabados y se redirige al index
            messages.success(request, 'Post editado correctamente')
            return redirect('blog:index')

    # Se genera el contexto y se renderiza
    context = {
        'title': 'Edit post',
        'post': post,
        'form': form,
    }
    return render(request, 'post_form.html', context)
示例#37
0
文件: views.py 项目: joskid/tbonline
def submit_article(request):
    '''
        View for Article Submission
    '''
    ImageFormset = formset_factory(ImageForm, extra=settings.MAX_NUM_IMAGES)
    if request.method == 'POST':
        form = ArticleSubmissionForm(request.POST, request.FILES)
        image_forms = ImageFormset(request.POST, request.FILES)
        if form.is_valid() and image_forms.is_valid():
            title = request.POST['title']
            subtitle = request.POST['subtitle']
            body = request.POST['body']
            editor = request.POST['editor']
            authors = request.POST.get('authors', [])
            tags = request.POST.get('tags', [])
            files = request.FILES
            post_body = EnhancedText(body, editor)                                  #Combines body and editor field to for creating post
            post = None
            if len(files) == 0:                                                     #Will save post as basic post
                post = BasicPost(title=title, slug=slugify(title), 
                                    subtitle=subtitle, body=post_body)
                post.slug = post._get_unique_slug()
                post.save()
            elif len(files) == 1:                                                   #Will save post as post with simple image
                image = None
                image = files.itervalues().next()
                post = PostWithSimpleImage(title=title, slug=slugify(title),
                                            subtitle=subtitle, body=post_body,
                                            image=image)
                post.save()
            else:                                                                   #Will save post as post with slideshow
                gallery = Gallery(title=title)
                gallery.save()
                path = os.path.join(settings.MEDIA_ROOT, 'uploads')
                path = os.path.join(path, 'images')
                for index, image in enumerate(files):
                    filename_unique = False
                    filename = os.path.join(path, files[image].name)
                    counter = 1
                    while not filename_unique:
                        if os.path.exists(filename):
                            filename_split = filename.split('.')
                            filename = filename_split[0]
                            extension = filename_split[1]
                            filename = filename + unicode(counter) + '.' + extension
                        else:
                            filename_unique = True
                    image_file = open(filename, 'wb+')
                    for chunk in files[image].chunks():
                        image_file.write(chunk)
                    image_file.close()
                    filename_split = filename.split(os.sep) 
                    base_filename = filename_split[-1]
                    filename = os.path.join('uploads', 'images')
                    filename = os.path.join(filename, base_filename)
                    image = Image(title=title, slug=slugify(title), file=filename)
                    image.slug = image._get_unique_slug()
                    image.save()
                    ordered_image = OrderedImage(gallery=gallery, image=image, position=index)
                    ordered_image.save()
                post = PostWithSlideshow(title=title, slug=slugify(title),
                                            subtitle=subtitle, body=post_body,
                                            gallery=gallery)
                post.save()
            if post:
                # Saves the authors and tags of the post
                for index, author in enumerate(authors):
                    credit = OrderedCredit(credit=Credit.objects.get(id=author), 
                                            content_object=post, position=index)
                    credit.save()
                for index, tag in enumerate(tags):
                    tag = TaggedItem(tag=Tag.objects.get(id=tag), object=post)
                    tag.save()
                article = SubmittedArticle(submitted_by=request.user, object=post)
                article.save()
            return HttpResponseRedirect(reverse('submit_article_success'))
    else:
        form = ArticleSubmissionForm()
        image_forms = ImageFormset()
    return render_to_response('submit_article/add.html',
                            {'form': form,
                            'image_forms': image_forms,
                            'max_forms': settings.MAX_NUM_IMAGES},
                            context_instance=RequestContext(request))