@@ -2,7 +2,7 @@  | 
            ||
| 2 | 2 | 
                 | 
            
| 3 | 3 | 
                from django.contrib import admin  | 
            
| 4 | 4 | 
                 | 
            
| 5 | 
                -from photo.models import PhotosInfo, UUIDInfo  | 
            |
| 5 | 
                +from photo.models import PhotosInfo, PhotoUUIDInfo, UUIDInfo  | 
            |
| 6 | 6 | 
                 | 
            
| 7 | 7 | 
                 | 
            
| 8 | 8 | 
                class UUIDInfoAdmin(admin.ModelAdmin):  | 
            
                @@ -10,6 +10,11 @@ class UUIDInfoAdmin(admin.ModelAdmin):  | 
            ||
| 10 | 10 | 
                     list_filter = ('lensman_id', 'status')
               | 
            
| 11 | 11 | 
                 | 
            
| 12 | 12 | 
                 | 
            
| 13 | 
                +class PhotoUUIDInfoAdmin(admin.ModelAdmin):  | 
            |
| 14 | 
                +    list_display = ('photo_md5', 'photo_path', 'status', 'created_at', 'updated_at')
               | 
            |
| 15 | 
                +    list_filter = ('status', )
               | 
            |
| 16 | 
                +  | 
            |
| 17 | 
                +  | 
            |
| 13 | 18 | 
                class PhotosInfoAdmin(admin.ModelAdmin):  | 
            
| 14 | 19 | 
                     list_display = ('lensman_id', 'session_id', 'photo_id', 'p_photo_path', 'm_photo_path', 'l_photo_path', 'r_photo_path', 'status', 'created_at', 'updated_at')
               | 
            
| 15 | 20 | 
                     list_filter = ('lensman_id', 'status')
               | 
            
                @@ -17,3 +22,4 @@ class PhotosInfoAdmin(admin.ModelAdmin):  | 
            ||
| 17 | 22 | 
                 | 
            
| 18 | 23 | 
                admin.site.register(UUIDInfo, UUIDInfoAdmin)  | 
            
| 19 | 24 | 
                admin.site.register(PhotosInfo, PhotosInfoAdmin)  | 
            
| 25 | 
                +admin.site.register(PhotoUUIDInfo, PhotoUUIDInfoAdmin)  | 
            
                @@ -0,0 +1,29 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +from __future__ import unicode_literals  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import models, migrations  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('photo', '0009_auto_20160907_1018'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.CreateModel(  | 
            |
| 15 | 
                + name='PhotoUUIDInfo',  | 
            |
| 16 | 
                + fields=[  | 
            |
| 17 | 
                +                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
               | 
            |
| 18 | 
                +                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
               | 
            |
| 19 | 
                +                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
               | 
            |
| 20 | 
                +                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
               | 
            |
| 21 | 
                +                ('photo_md5', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_md5', db_index=True)),
               | 
            |
| 22 | 
                +                ('photo_path', models.CharField(help_text='\u7167\u7247\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
               | 
            |
| 23 | 
                + ],  | 
            |
| 24 | 
                +            options={
               | 
            |
| 25 | 
                + 'verbose_name': 'photouuidinfo',  | 
            |
| 26 | 
                + 'verbose_name_plural': 'photouuidinfo',  | 
            |
| 27 | 
                + },  | 
            |
| 28 | 
                + ),  | 
            |
| 29 | 
                + ]  | 
            
                @@ -27,6 +27,18 @@ class UUIDInfo(CreateUpdateMixin):  | 
            ||
| 27 | 27 | 
                }  | 
            
| 28 | 28 | 
                 | 
            
| 29 | 29 | 
                 | 
            
| 30 | 
                +class PhotoUUIDInfo(CreateUpdateMixin):  | 
            |
| 31 | 
                + photo_md5 = models.CharField(_(u'photo_md5'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True)  | 
            |
| 32 | 
                + photo_path = models.CharField(_(u'photo_path'), max_length=255, blank=True, null=True, help_text=u'照片路径')  | 
            |
| 33 | 
                +  | 
            |
| 34 | 
                + class Meta:  | 
            |
| 35 | 
                +        verbose_name = _('photouuidinfo')
               | 
            |
| 36 | 
                +        verbose_name_plural = _('photouuidinfo')
               | 
            |
| 37 | 
                +  | 
            |
| 38 | 
                + def __unicode__(self):  | 
            |
| 39 | 
                +        return u'{0.pk}'.format(self)
               | 
            |
| 40 | 
                +  | 
            |
| 41 | 
                +  | 
            |
| 30 | 42 | 
                class PhotosInfo(CreateUpdateMixin):  | 
            
| 31 | 43 | 
                lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)  | 
            
| 32 | 44 | 
                session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)  | 
            
                @@ -9,6 +9,7 @@ TimeConvert==1.3.12  | 
            ||
| 9 | 9 | 
                cryptography==1.5.2  | 
            
| 10 | 10 | 
                django-curtail-uuid==1.0.0  | 
            
| 11 | 11 | 
                django-detect==1.0.5  | 
            
| 12 | 
                +django-file-md5==1.0.0  | 
            |
| 12 | 13 | 
                django-ip==1.0.0  | 
            
| 13 | 14 | 
                django-json-response==1.1.4  | 
            
| 14 | 15 | 
                django-logit==1.0.6  | 
            
                @@ -4,12 +4,25 @@ import os  | 
            ||
| 4 | 4 | 
                 | 
            
| 5 | 5 | 
                import shortuuid  | 
            
| 6 | 6 | 
                from django.core.files.storage import default_storage  | 
            
| 7 | 
                +from django.db import transaction  | 
            |
| 8 | 
                +from filemd5 import calculate_md5  | 
            |
| 7 | 9 | 
                 | 
            
| 10 | 
                +from photo.models import PhotoUUIDInfo  | 
            |
| 8 | 11 | 
                 | 
            
| 12 | 
                +  | 
            |
| 13 | 
                +@transaction.atomic  | 
            |
| 9 | 14 | 
                def file_save(file_, prefix='img', ext='jpeg'):  | 
            
| 10 | 15 | 
                ext = os.path.splitext(file_.name)[-1] or ext  | 
            
| 11 | 
                -    path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext)
               | 
            |
| 12 | 
                - if default_storage.exists(path):  | 
            |
| 13 | 
                - default_storage.delete(path)  | 
            |
| 14 | 
                - default_storage.save(path, file_)  | 
            |
| 15 | 
                - return path, ext  | 
            |
| 16 | 
                +  | 
            |
| 17 | 
                + photo, created = PhotoUUIDInfo.objects.select_for_update().get_or_create(photo_md5=calculate_md5(file_))  | 
            |
| 18 | 
                +  | 
            |
| 19 | 
                + if not photo.photo_path:  | 
            |
| 20 | 
                +        path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext)
               | 
            |
| 21 | 
                + if default_storage.exists(path):  | 
            |
| 22 | 
                + default_storage.delete(path)  | 
            |
| 23 | 
                + default_storage.save(path, file_)  | 
            |
| 24 | 
                +  | 
            |
| 25 | 
                + photo.photo_path = path  | 
            |
| 26 | 
                + photo.save()  | 
            |
| 27 | 
                +  | 
            |
| 28 | 
                + return photo.photo_path, ext  |