14
+    list_display = ('photo_md5', 'photo_path', 'photo_watermark_path', 'photo_thumbnail_path', 'photo_thumbnail2_path', 'status', 'created_at', 'updated_at')
15 15
     list_filter = ('status', )
16 16
 
17 17
 

+ 69 - 0
photo/migrations/0011_auto_20170119_1207.py

@@ -0,0 +1,69 @@
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', '0010_photouuidinfo'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='photouuidinfo',
16
+            name='photo_h',
17
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u9ad8\u5ea6', verbose_name='photo_h'),
18
+        ),
19
+        migrations.AddField(
20
+            model_name='photouuidinfo',
21
+            name='photo_thumbnail2_h',
22
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail2_h'),
23
+        ),
24
+        migrations.AddField(
25
+            model_name='photouuidinfo',
26
+            name='photo_thumbnail2_path',
27
+            field=models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail2_path', blank=True),
28
+        ),
29
+        migrations.AddField(
30
+            model_name='photouuidinfo',
31
+            name='photo_thumbnail2_w',
32
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail2_w'),
33
+        ),
34
+        migrations.AddField(
35
+            model_name='photouuidinfo',
36
+            name='photo_thumbnail_h',
37
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u9ad8\u5ea6', verbose_name='photo_thumbnail_h'),
38
+        ),
39
+        migrations.AddField(
40
+            model_name='photouuidinfo',
41
+            name='photo_thumbnail_path',
42
+            field=models.CharField(help_text='\u7167\u7247\u7f29\u7565\u56fe\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_thumbnail_path', blank=True),
43
+        ),
44
+        migrations.AddField(
45
+            model_name='photouuidinfo',
46
+            name='photo_thumbnail_w',
47
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u7f29\u7565\u56fe\u5bbd\u5ea6', verbose_name='photo_thumbnail_w'),
48
+        ),
49
+        migrations.AddField(
50
+            model_name='photouuidinfo',
51
+            name='photo_w',
52
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u5bbd\u5ea6', verbose_name='photo_w'),
53
+        ),
54
+        migrations.AddField(
55
+            model_name='photouuidinfo',
56
+            name='photo_watermark_h',
57
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u6c34\u5370\u56fe\u9ad8\u5ea6', verbose_name='photo_watermark_h'),
58
+        ),
59
+        migrations.AddField(
60
+            model_name='photouuidinfo',
61
+            name='photo_watermark_path',
62
+            field=models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84\uff0cBox\u4e0a\u4f20\uff0c\u6709\u6c34\u5370\uff0c\u670d\u52a1\u5668\u6dfb\u52a0', max_length=255, null=True, verbose_name='photo_watermark_path', blank=True),
63
+        ),
64
+        migrations.AddField(
65
+            model_name='photouuidinfo',
66
+            name='photo_watermark_w',
67
+            field=models.IntegerField(default=0, help_text='\u7167\u7247\u6c34\u5370\u56fe\u5bbd\u5ea6', verbose_name='photo_watermark_w'),
68
+        ),
69
+    ]

+ 15 - 0
photo/models.py

@@ -29,7 +29,22 @@ class UUIDInfo(CreateUpdateMixin):
29 29
 
30 30
 class PhotoUUIDInfo(CreateUpdateMixin):
31 31
     photo_md5 = models.CharField(_(u'photo_md5'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True)
32
+
32 33
     photo_path = models.CharField(_(u'photo_path'), max_length=255, blank=True, null=True, help_text=u'照片路径')
34
+    photo_w = models.IntegerField(_(u'photo_w'), default=0, help_text=u'照片宽度')
35
+    photo_h = models.IntegerField(_(u'photo_h'), default=0, help_text=u'照片高度')
36
+
37
+    photo_watermark_path = models.CharField(_(u'photo_watermark_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径,Box上传,有水印,服务器添加')
38
+    photo_watermark_w = models.IntegerField(_(u'photo_watermark_w'), default=0, help_text=u'照片水印图宽度')
39
+    photo_watermark_h = models.IntegerField(_(u'photo_watermark_h'), default=0, help_text=u'照片水印图高度')
40
+
41
+    photo_thumbnail_path = models.CharField(_(u'photo_thumbnail_path'), max_length=255, blank=True, null=True, help_text=u'照片缩略图存放路径')
42
+    photo_thumbnail_w = models.IntegerField(_(u'photo_thumbnail_w'), default=0, help_text=u'照片缩略图宽度')
43
+    photo_thumbnail_h = models.IntegerField(_(u'photo_thumbnail_h'), default=0, help_text=u'照片缩略图高度')
44
+
45
+    photo_thumbnail2_path = models.CharField(_(u'photo_thumbnail2_path'), max_length=255, blank=True, null=True, help_text=u'照片缩略图存放路径')
46
+    photo_thumbnail2_w = models.IntegerField(_(u'photo_thumbnail2_w'), default=0, help_text=u'照片缩略图宽度')
47
+    photo_thumbnail2_h = models.IntegerField(_(u'photo_thumbnail2_h'), default=0, help_text=u'照片缩略图高度')
33 48
 
34 49
     class Meta:
35 50
         verbose_name = _('photouuidinfo')

+ 3 - 10
photo/views.py

@@ -91,21 +91,14 @@ def upload_photo(request):
91 91
     except LensmanInfo.DoesNotExist:
92 92
         return response(LensmanStatusCode.LENSMAN_NOT_FOUND)
93 93
 
94
-    m_photo_path, ext = file_save(photo, prefix='photo', ext='jpeg')
95
-
96
-    p_photo_path = 'photo/{}{}'.format(shortuuid.uuid(), ext)
97
-    watermark_wrap(
98
-        os.path.join(settings.MEDIA_ROOT, m_photo_path).replace('\\', '/'),
99
-        settings.WATERMARK_LOGO,
100
-        os.path.join(settings.MEDIA_ROOT, p_photo_path).replace('\\', '/')
101
-    )
94
+    photo_info = file_save(photo, prefix='photo', ext='jpeg', watermark=True)
102 95
 
103 96
     photo, created = PhotosInfo.objects.get_or_create(
104 97
         lensman_id=lensman_id,
105 98
         session_id=session_id,
106 99
         photo_id=photo_id,
107
-        p_photo_path=p_photo_path,
108
-        m_photo_path=m_photo_path,
100
+        p_photo_path=photo_info.photo_watermark_path,
101
+        m_photo_path=photo_info.photo_path,
109 102
     )
110 103
 
111 104
     return response(200, 'Photo Upload Success', u'照片上传成功', photo.data)

+ 1 - 1
requirements.txt

@@ -29,7 +29,7 @@ mock==2.0.0
29 29
 pep8==1.7.0
30 30
 pywe-oauth==1.0.2
31 31
 records==0.4.3
32
-redis-extensions==1.0.36
32
+redis-extensions==1.0.37
33 33
 requests==2.12.4
34 34
 rlog==0.2
35 35
 shortuuid==0.4.3

+ 76 - 8
utils/storage_utils.py

@@ -3,26 +3,94 @@
3 3
 import os
4 4
 
5 5
 import shortuuid
6
+from django.conf import settings
6 7
 from django.core.files.storage import default_storage
7 8
 from django.db import transaction
8 9
 from filemd5 import calculate_md5
9 10
 
10 11
 from photo.models import PhotoUUIDInfo
12
+from utils.thumbnail_utils import make_thumbnail
13
+from utils.watermark_utils import watermark_wrap
14
+
15
+
16
+class DotDict(dict):
17
+    """ dot.notation access to dictionary attributes """
18
+    def __getattr__(self, attr):
19
+        return self.get(attr)
20
+    __setattr__ = dict.__setitem__
21
+    __delattr__ = dict.__delitem__
11 22
 
12 23
 
13 24
 @transaction.atomic
14
-def file_save(file_, prefix='img', ext='jpeg'):
25
+def file_save(file_, prefix='img', ext='jpeg', watermark=False, thumbnail=False):
15 26
     ext = os.path.splitext(file_.name)[-1] or ext
16 27
 
17 28
     photo, created = PhotoUUIDInfo.objects.select_for_update().get_or_create(photo_md5=calculate_md5(file_))
18 29
 
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_)
30
+    photo_path = photo.photo_path
31
+    if not photo_path:
32
+        photo_path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext)
33
+        if default_storage.exists(photo_path):
34
+            default_storage.delete(photo_path)
35
+        default_storage.save(photo_path, file_)
36
+
37
+        photo.photo_path = photo_path
38
+        photo.save()
39
+
40
+    if watermark:
41
+        if not photo.photo_watermark_path:
42
+            photo_watermark_path = 'photo/{}{}'.format(shortuuid.uuid(), ext)
43
+            watermark_wrap(
44
+                os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'),
45
+                settings.WATERMARK_LOGO,
46
+                os.path.join(settings.MEDIA_ROOT, photo_watermark_path).replace('\\', '/')
47
+            )
48
+            photo.photo_watermark_path
49
+            photo.save()
24 50
 
25
-        photo.photo_path = path
51
+    if thumbnail:
52
+        if not photo.photo_thumbnail_path:
53
+            # 双列: 540, 40-50K
54
+            photo_thumbnail_path = photo_path.replace('.', '_thumbnail.')
55
+            photo_w, photo_h, photo_thumbnail_w, photo_thumbnail_h = make_thumbnail(
56
+                os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'),
57
+                os.path.join(settings.MEDIA_ROOT, photo_thumbnail_path).replace('\\', '/'),
58
+                settings.THUMBNAIL_MAX_WIDTH
59
+            )
60
+            photo.photo_w = photo_w
61
+            photo.photo_h = photo_h
62
+            photo.photo_thumbnail_path = photo_thumbnail_path
63
+            photo.photo_thumbnail_w = photo_thumbnail_w
64
+            photo.photo_thumbnail_h = photo_thumbnail_h
65
+        if not photo.photo_thumbnail2_path:
66
+            # 单列: 1080, xx-100K
67
+            photo_thumbnail2_path = photo_path.replace('.', '_thumbnail2.')
68
+            photo_w, photo_h, photo_thumbnail2_w, photo_thumbnail2_h = make_thumbnail(
69
+                os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'),
70
+                os.path.join(settings.MEDIA_ROOT, photo_thumbnail2_path).replace('\\', '/'),
71
+                settings.THUMBNAIL_MAX_WIDTH2
72
+            )
73
+            photo.photo_w = photo_w
74
+            photo.photo_h = photo_h
75
+            photo.photo_thumbnail2_path = photo_thumbnail2_path
76
+            photo.photo_thumbnail2_w = photo_thumbnail2_w
77
+            photo.photo_thumbnail2_h = photo_thumbnail2_h
26 78
         photo.save()
27 79
 
28
-    return photo.photo_path, ext
80
+    return DotDict({
81
+        'ext': ext,
82
+
83
+        'photo_path': photo_path,
84
+        'photo_w': photo.photo_w,
85
+        'photo_h': photo.photo_h,
86
+
87
+        'photo_watermark_path': photo.photo_watermark_path,
88
+
89
+        'photo_thumbnail_path': photo.photo_thumbnail_path,
90
+        'photo_thumbnail_w': photo.photo_thumbnail_w,
91
+        'photo_thumbnail_h': photo.photo_thumbnail_h,
92
+
93
+        'photo_thumbnail2_path': photo.photo_thumbnail2_path,
94
+        'photo_thumbnail2_w': photo.photo_thumbnail2_w,
95
+        'photo_thumbnail2_h': photo.photo_thumbnail2_h,
96
+    })

kodo - Gogs: Go Git Service

Sin Descripción

huangqimin001: 96c4bec605 :art: Add api activity_group_share %!s(int64=5) %!d(string=hace) años
..
0001_initial.py 88c914df41 Guideline Login Error %!s(int64=7) %!d(string=hace) años
0002_auto_20181117_0052.py b8784eee8a Makemigrations %!s(int64=7) %!d(string=hace) años
0003_auto_20190826_1537.py 8d998319f7 Makemigrations %!s(int64=6) %!d(string=hace) años
0004_auto_20201130_0131.py 96c4bec605 :art: Add api activity_group_share %!s(int64=5) %!d(string=hace) años
__init__.py 88c914df41 Guideline Login Error %!s(int64=7) %!d(string=hace) años