add api uuid_init/uuid

Brightcells %!s(int64=9) %!d(string=hace) años
padre
commit
52ce35cbfc

+ 2 - 0
api/urls.py

@@ -6,5 +6,7 @@ from photo import views as photo_views
6 6
 
7 7
 
8 8
 urlpatterns = [
9
+    url(r'^uuid_init$', photo_views.uuid_init, name='uuid_init'),
10
+    url(r'^uuid$', photo_views.uuid, name='uuid'),
9 11
     url(r'^photos/upload$', photo_views.upload_photo, name='upload_photo'),
10 12
 ]

+ 4 - 0
docs/errorcode

@@ -0,0 +1,4 @@
1
+1、照片上传 —— 401
2
+     4010 —— 参数错误
3
+     4011 —— 摄影师不存在
4
+     4012 —— 照片已存在

+ 1 - 1
pai2/urls.py

@@ -40,7 +40,7 @@ urlpatterns += [
40 40
 # Wire up our API using automatic URL routing.
41 41
 # Additionally, we include login URLs for the browsable API.
42 42
 urlpatterns += [
43
-    url(r'^api/', include(router.urls)),
43
+    url(r'^apihome/', include(router.urls)),
44 44
     url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
45 45
 ]
46 46
 

+ 4 - 0
pai2/uwsgi.bak/pai2_nginx.conf

@@ -26,6 +26,10 @@ server {
26 26
         alias /home/paiai/work/pai2/collect_static; # your Django project's static files - amend as required
27 27
     }
28 28
 
29
+    location /p/  {
30
+        alias /home/paiai/work/pai2/media/photo;  # Photo
31
+    }
32
+
29 33
     # Finally, send all non-media requests to the Django server.
30 34
     location / {
31 35
         # uwsgi_pass  pai2;

+ 8 - 2
photo/admin.py

@@ -2,12 +2,18 @@
2 2
 
3 3
 from django.contrib import admin
4 4
 
5
-from photo.models import PhotosInfo
5
+from photo.models import UUIDInfo, PhotosInfo
6
+
7
+
8
+class UUIDInfoAdmin(admin.ModelAdmin):
9
+    list_display = ('uuid', 'lensman_id', 'status', 'created_at', 'updated_at')
10
+    list_filter = ('lensman_id', 'status')
6 11
 
7 12
 
8 13
 class PhotosInfoAdmin(admin.ModelAdmin):
9
-    list_display = ('lensman_id', 'session_id', 'photo_id', 'photo_path', 'status', 'created_at', 'updated_at')
14
+    list_display = ('lensman_id', 'session_id', 'photo_id', 'photo_name', 'photo_path', 'status', 'created_at', 'updated_at')
10 15
     list_filter = ('lensman_id', 'status')
11 16
 
12 17
 
18
+admin.site.register(UUIDInfo, UUIDInfoAdmin)
13 19
 admin.site.register(PhotosInfo, PhotosInfoAdmin)

+ 29 - 0
photo/migrations/0003_uuidinfo.py

@@ -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', '0002_auto_20151113_1419'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='UUIDInfo',
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', 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
+                ('uuid', models.CharField(null=True, max_length=22, blank=True, help_text='\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='uuid', db_index=True)),
22
+                ('lensman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lensman_id', db_index=True)),
23
+            ],
24
+            options={
25
+                'verbose_name': 'uuidinfo',
26
+                'verbose_name_plural': 'uuidinfo',
27
+            },
28
+        ),
29
+    ]

+ 19 - 0
photo/migrations/0004_photosinfo_photo_name.py

@@ -0,0 +1,19 @@
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', '0003_uuidinfo'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='photosinfo',
16
+            name='photo_name',
17
+            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u540d\u79f0', max_length=255, null=True, verbose_name='photo_name', blank=True),
18
+        ),
19
+    ]

+ 24 - 1
photo/models.py

@@ -7,10 +7,32 @@ from django.utils.translation import ugettext_lazy as _
7 7
 from pai2.basemodels import CreateUpdateMixin
8 8
 
9 9
 
10
+class UUIDInfo(CreateUpdateMixin):
11
+    uuid = models.CharField(_(u'uuid'), max_length=22, blank=True, null=True, help_text=u'唯一标识', db_index=True, unique=True)
12
+    lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
13
+
14
+    class Meta:
15
+        verbose_name = _('uuidinfo')
16
+        verbose_name_plural = _('uuidinfo')
17
+
18
+    def __unicode__(self):
19
+        return u'{0.pk}'.format(self)
20
+
21
+    def _data(self):
22
+        return {
23
+            'pk': self.pk,
24
+            'uuid': self.uuid,
25
+            'lensman_id': self.lensman_id,
26
+        }
27
+
28
+    data = property(_data)
29
+
30
+
10 31
 class PhotosInfo(CreateUpdateMixin):
11 32
     lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
12 33
     session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)
13 34
     photo_id = models.CharField(_(u'photo_id'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True)
35
+    photo_name = models.CharField(_(u'photo_name'), max_length=255, blank=True, null=True, help_text=u'照片存放名称')
14 36
     photo_path = models.CharField(_(u'photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径')
15 37
 
16 38
     class Meta:
@@ -25,7 +47,8 @@ class PhotosInfo(CreateUpdateMixin):
25 47
 
26 48
     @property
27 49
     def photo_url(self):
28
-        return u'{0}/media/{1}'.format(settings.DOMAIN, self.photo_path) if self.photo_path else ''
50
+        # return u'{0}/media/{1}'.format(settings.DOMAIN, self.photo_path) if self.photo_path else ''
51
+        return u'{0}/p/{1}'.format(settings.DOMAIN, self.photo_name) if self.photo_name else ''
29 52
 
30 53
     def _data(self):
31 54
         return {

+ 47 - 8
photo/views.py

@@ -1,17 +1,52 @@
1 1
 # -*- coding: utf-8 -*-
2 2
 
3 3
 from django.core.files.storage import default_storage
4
+from django.db import transaction
4 5
 from django.http import JsonResponse
5 6
 
6 7
 from rest_framework import viewsets
7 8
 
8 9
 from account.models import LensmanInfo
9
-from photo.models import PhotosInfo
10
+from photo.models import UUIDInfo, PhotosInfo
10 11
 from photo.serializers import PhotosInfoSerializer
11 12
 
13
+from utils.uuid_utils import curtailUUID
14
+
12 15
 import os
13 16
 
14 17
 
18
+def uuid_init(request):
19
+    num = int(request.GET.get('num', 1000))
20
+
21
+    for i in xrange(num):
22
+        UUIDInfo.objects.create(uuid=curtailUUID())
23
+
24
+    return JsonResponse({
25
+        'status': 200,
26
+        'message': u'UUID 更新成功',
27
+        'data': '',
28
+    })
29
+
30
+
31
+# curl -X POST -F lensman_id=123 -F num=100 http://xfoto.com.cn/api/uuid
32
+@transaction.atomic
33
+def uuid(request):
34
+    lensman_id = request.POST.get('lensman_id', '')
35
+    num = int(request.POST.get('num', 100))
36
+
37
+    uuids = UUIDInfo.objects.select_for_update().filter(status=True)[:num]
38
+    for uuid in uuids:
39
+        uuid.lensman_id = lensman_id
40
+        uuid.status = False
41
+        uuid.save()
42
+
43
+    return JsonResponse({
44
+        'status': 200,
45
+        'message': u'获取唯一标识成功',
46
+        'data': [uuid.uuid for uuid in uuids],
47
+    })
48
+
49
+
15 50
 # [How to do a PUT request with curl?](http://stackoverflow.com/questions/13782198/how-to-do-a-put-request-with-curl)
16 51
 # Unfortunately, the -T is no substitute for -X PUT if you want to specify parameters with -d or -F.
17 52
 # -T sends the content of a file via PUT. To achieve the GET after a redirect, add the parameter --location
@@ -23,17 +58,16 @@ import os
23 58
 #               name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file  upload,
24 59
 #               while the < makes a text field and just get the contents for that text field from a file.
25 60
 #
26
-# curl -X POST -F lensman_id=123 -F session_id=456 -F photo_id=789 -F photo=@7056288a9ddf2db294cf50a943920989.jpg;filename=789 http://xfoto.com.cn/api/photos/upload
61
+# curl -X POST -F lensman_id=123 -F session_id=456 -F photo=@7056288a9ddf2db294cf50a943920989.jpg;filename=789 http://xfoto.com.cn/api/photos/upload
27 62
 def upload_photo(request):
28 63
     lensman_id = request.POST.get('lensman_id', '')
29 64
     session_id = request.POST.get('session_id', '')
30
-    photo_id = request.POST.get('photo_id', '')
31 65
 
32 66
     photo = request.FILES.get('photo', '')
33 67
 
34
-    if not (lensman_id and session_id and photo_id and photo):
68
+    if not (lensman_id and session_id and photo):
35 69
         return JsonResponse({
36
-            'status': 400,
70
+            'status': 4010,
37 71
             'message': u'参数错误',
38 72
         })
39 73
 
@@ -41,12 +75,16 @@ def upload_photo(request):
41 75
         LensmanInfo.objects.get(lensman_id=lensman_id)
42 76
     except LensmanInfo.DoesNotExist:
43 77
         return JsonResponse({
44
-            'status': 400,
45
-            'message': u'参数错误',
78
+            'status': 4011,
79
+            'message': u'摄影师不存在',
46 80
         })
47 81
 
82
+    photo_id = curtailUUID()
83
+
48 84
     _, extension = os.path.splitext(photo.name)
49
-    photo_path = 'photo/{0}/{1}/{2}{3}'.format(lensman_id, session_id, photo_id, extension)
85
+    # photo_path = 'photo/{0}/{1}/{2}{3}'.format(lensman_id, session_id, photo_id, extension)
86
+    photo_name = '{0}{1}'.format(photo_id, extension)
87
+    photo_path = 'photo/{0}'.format(photo_name)
50 88
 
51 89
     if default_storage.exists(photo_path):
52 90
         default_storage.delete(photo_path)
@@ -56,6 +94,7 @@ def upload_photo(request):
56 94
         lensman_id=lensman_id,
57 95
         session_id=session_id,
58 96
         photo_id=photo_id,
97
+        photo_name=photo_name,
59 98
         photo_path=photo_path
60 99
     )
61 100
 

+ 1 - 0
requirements.txt

@@ -9,4 +9,5 @@ ipython==4.0.0
9 9
 pep8==1.6.2
10 10
 pillow==2.9.0
11 11
 pytz==2015.7
12
+shortuuid==0.4.2
12 13
 uWSGI==2.0.11.1

+ 0 - 0
utils/__init__.py


+ 16 - 0
utils/uuid_utils.py

@@ -0,0 +1,16 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from photo.models import UUIDInfo
4
+
5
+import shortuuid
6
+
7
+
8
+def curtailUUID(length=10):
9
+    flag = True
10
+    while flag:
11
+        uuid = shortuuid.uuid()[-length:]
12
+        try:
13
+            UUIDInfo.objects.get(uuid=uuid)
14
+        except UUIDInfo.DoesNotExist:
15
+            flag = False
16
+    return uuid