rel="diff-193e383b563255ba74ac8c95c1393f1d174104b2R90">90
 
91 91
     @property
92 92
     def r_photo_url(self):
93
-        return img_url(self.r_photo_path)
93
+        return qiniu_file_url(self.r_photo_path, bucket='original')
94 94
 
95 95
     @property
96 96
     def data(self):

+ 1 - 1
photo/views.py

@@ -21,7 +21,7 @@ from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_USERS_DELETED_SET, GRO
21 21
                                GROUP_USERS_QUIT_SET, GROUP_USERS_REFUSED_SET, UUID_LIST)
22 22
 from utils.redis.rprice import get_lensman_price_fixed
23 23
 from utils.redis.ruuid import generate_uuids, update_uuids
24
-from utils.storage_utils import file_save
24
+from utils.storage_qiniu_utils import file_save
25 25
 
26 26
 
27 27
 @logit

+ 5 - 4
requirements.txt

@@ -18,21 +18,22 @@ django-paginator2==1.0.3
18 18
 django-rlog==1.0.7
19 19
 django-shortuuidfield==0.1.3
20 20
 django-six==1.0.2
21
-djangorestframework==3.5.3
22
-furl==0.5.7
21
+djangorestframework==3.6.3
22
+furl==1.0.0
23 23
 hiredis==0.2.0
24 24
 isoweek==1.3.3
25
-jsonfield==2.0.1
25
+jsonfield==2.0.2
26 26
 mock==2.0.0
27 27
 pep8==1.7.0
28 28
 pysnippets==1.0.4
29 29
 pywe-miniapp==1.0.0
30 30
 pywe-oauth==1.0.3
31 31
 pywe-response==1.0.1
32
+qiniu==7.1.4
32 33
 redis-extensions==1.0.50
33 34
 requests==2.12.4
34 35
 rlog==0.2
35 36
 shortuuid==0.5.0
36
-uWSGI==2.0.14
37
+uWSGI==2.0.15
37 38
 versions==0.10.0
38 39
 wechatpy==1.2.8

+ 43 - 0
utils/qiniucdn.py

@@ -0,0 +1,43 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+import qiniu
4
+from django.conf import settings
5
+
6
+
7
+QINIU = settings.QINIU
8
+auth = qiniu.Auth(QINIU['access_key'], QINIU['secret_key'])
9
+
10
+
11
+def upload(data, key=None, mime_type='application/octet-stream', bucket=QINIU['bucket_default']):
12
+    if not data:
13
+        return ''
14
+    token = auth.upload_token(bucket, key=key)
15
+    ret, _ = qiniu.put_data(token, key, data, mime_type=mime_type)
16
+    return ret.get('key')
17
+
18
+
19
+def upload_file_admin(obj, key=None, mime_type='application/octet-stream', bucket=QINIU['bucket_default']):
20
+    # Django Admin Upload
21
+    if not obj.image:
22
+        return ''
23
+    return upload(obj.image.read(), key=key, mime_type=mime_type, bucket=bucket)
24
+
25
+
26
+def upload_file_req(photo, key=None, mime_type='application/octet-stream', bucket=QINIU['bucket_default']):
27
+    # photo = request.FILES.get('photo', '')
28
+    # <InMemoryUploadedFile: photo.png (image/png)>
29
+    if not photo:
30
+        return ''
31
+    return upload(photo.read(), key=key, mime_type=mime_type, bucket=bucket)
32
+
33
+
34
+def upload_file_path(path, key=None, mime_type='application/octet-stream', bucket=QINIU['bucket_default']):
35
+    if not path:
36
+        return ''
37
+    token = auth.upload_token(bucket, key=key)
38
+    ret, _ = qiniu.put_file(token, key, path, mime_type=mime_type)
39
+    return ret.get('key')
40
+
41
+
42
+def qiniu_file_url(key, bucket):
43
+    return '{}/{}'.format(QINIU['buckets'][bucket], key)

+ 135 - 0
utils/storage_qiniu_utils.py

@@ -0,0 +1,135 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+import os
4
+
5
+import shortuuid
6
+from django.conf import settings
7
+from django.core.files.storage import default_storage
8
+from django.db import transaction
9
+from filemd5 import calculate_md5
10
+
11
+from photo.models import PhotoUUIDInfo
12
+from utils.qiniucdn import upload_file_path
13
+from utils.thumbnail_utils import make_thumbnail
14
+from utils.watermark_utils import watermark_wrap
15
+
16
+
17
+class DotDict(dict):
18
+    """ dot.notation access to dictionary attributes """
19
+    def __getattr__(self, attr):
20
+        return self.get(attr)
21
+    __setattr__ = dict.__setitem__
22
+    __delattr__ = dict.__delitem__
23
+
24
+
25
+def file_abspath(file_path=None):
26
+    return os.path.join(settings.MEDIA_ROOT, file_path).replace('\\', '/')
27
+
28
+
29
+@transaction.atomic
30
+def file_save(file_=None, file_path=None, prefix='img', ext='.jpeg', watermark=False, thumbnail=False):
31
+    photo_path, photo_watermark_path, photo_thumbnail_path, photo_thumbnail2_path = '', '', '', ''
32
+
33
+    # Photo
34
+    file_ = file_ or default_storage.open(file_path)
35
+
36
+    # Ext
37
+    ext = os.path.splitext(file_.name)[-1] or ext
38
+
39
+    # Photo MD5
40
+    photo_md5 = calculate_md5(file_)
41
+
42
+    # Photo UUID Get or Create
43
+    photo, created = PhotoUUIDInfo.objects.select_for_update().get_or_create(photo_md5=photo_md5)
44
+
45
+    # 无水印
46
+    if not photo.photo_path:
47
+        photo_path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext)
48
+        if default_storage.exists(photo_path):
49
+            default_storage.delete(photo_path)
50
+        default_storage.save(photo_path, file_)
51
+        photo_path_qiniu = upload_file_path(file_abspath(photo_path), bucket='photo')
52
+        photo.photo_path = photo_path_qiniu
53
+        photo.save()
54
+    else:
55
+        if ((watermark and not photo.photo_watermark_path) or (thumbnail and not (photo.photo_thumbnail_path and photo.photo_thumbnail2_path))) and (not default_storage.exists(photo.photo_path)):
56
+            default_storage.save(photo.photo_path, file_)
57
+
58
+    # 有水印
59
+    if watermark:
60
+        if not photo.photo_watermark_path:
61
+            if settings.WATERMARK_OR_NOT:
62
+                photo_watermark_path = 'photo/{}{}'.format(shortuuid.uuid(), ext)
63
+                watermark_wrap(
64
+                    file_abspath(photo_path),
65
+                    settings.WATERMARK_LOGO_PATH,
66
+                    file_abspath(photo_watermark_path)
67
+                )
68
+                photo_watermark_path_qiniu = upload_file_path(file_abspath(photo_watermark_path), bucket='watermark')
69
+                photo.photo_watermark_path = photo_watermark_path_qiniu
70
+            else:
71
+                photo.photo_watermark_path = photo_path_qiniu
72
+            photo.save()
73
+
74
+    # 缩略图
75
+    if thumbnail:
76
+        if not photo.photo_thumbnail_path:
77
+            # 双列: 540, 40-50K
78
+            photo_thumbnail_path = photo_path.replace('.', '_thumbnail.')
79
+            photo_w, photo_h, photo_thumbnail_w, photo_thumbnail_h = make_thumbnail(
80
+                file_abspath(photo_path),
81
+                file_abspath(photo_thumbnail_path),
82
+                settings.THUMBNAIL_MAX_WIDTH
83
+            )
84
+            photo_thumbnail_path_qiniu = upload_file_path(file_abspath(photo_thumbnail_path), bucket='thumbnail')
85
+            photo.photo_w = photo_w
86
+            photo.photo_h = photo_h
87
+            photo.photo_thumbnail_path = photo_thumbnail_path_qiniu
88
+            photo.photo_thumbnail_w = photo_thumbnail_w
89
+            photo.photo_thumbnail_h = photo_thumbnail_h
90
+        if not photo.photo_thumbnail2_path:
91
+            # 单列: 1080, xx-100K
92
+            photo_thumbnail2_path = photo_path.replace('.', '_thumbnail2.')
93
+            photo_w, photo_h, photo_thumbnail2_w, photo_thumbnail2_h = make_thumbnail(
94
+                file_abspath(photo_path),
95
+                file_abspath(photo_thumbnail2_path),
96
+                settings.THUMBNAIL_MAX_WIDTH2
97
+            )
98
+            if watermark and settings.WATERMARK_OR_NOT:
99
+                watermark_wrap(
100
+                    file_abspath(photo_thumbnail2_path),
101
+                    settings.WATERMARK_LOGO_PATH,
102
+                    file_abspath(photo_thumbnail2_path)
103
+                )
104
+            photo_thumbnail2_path_qiniu = upload_file_path(file_abspath(photo_thumbnail2_path), bucket='thumbnail2')
105
+            photo.photo_w = photo_w
106
+            photo.photo_h = photo_h
107
+            photo.photo_thumbnail2_path = photo_thumbnail2_path_qiniu
108
+            photo.photo_thumbnail2_w = photo_thumbnail2_w
109
+            photo.photo_thumbnail2_h = photo_thumbnail2_h
110
+        photo.save()
111
+
112
+    # 本地删除
113
+    for path in [photo_path, photo_watermark_path, photo_thumbnail_path, photo_thumbnail2_path]:
114
+        if path and default_storage.exists(path):
115
+            default_storage.delete(path)
116
+
117
+    return DotDict({
118
+        'ext': ext,
119
+
120
+        'photo_md5': photo_md5,
121
+
122
+        'photo_path': photo.photo_path,
123
+        'photo_w': photo.photo_w,
124
+        'photo_h': photo.photo_h,
125
+
126
+        'photo_watermark_path': photo.photo_watermark_path,
127
+
128
+        'photo_thumbnail_path': photo.photo_thumbnail_path,
129
+        'photo_thumbnail_w': photo.photo_thumbnail_w,
130
+        'photo_thumbnail_h': photo.photo_thumbnail_h,
131
+
132
+        'photo_thumbnail2_path': photo.photo_thumbnail2_path,
133
+        'photo_thumbnail2_w': photo.photo_thumbnail2_w,
134
+        'photo_thumbnail2_h': photo.photo_thumbnail2_h,
135
+    })

+ 0 - 4
utils/url_utils.py

@@ -3,10 +3,6 @@
3 3
 from django.conf import settings
4 4
 
5 5
 
6
-def img_url(img_path):
7
-    return '{}/{}'.format(settings.IMG_DOMAIN, img_path) if img_path else ''
8
-
9
-
10 6
 def share_url(photo_id):
11 7
     return '{}/gp/{}'.format(settings.DOMAIN, photo_id) if photo_id else ''
12 8
 

https://pypi.python.org/pypi/django-curtail-uuid · 6e77deb909 - Gogs: Go Git Service

https://pypi.python.org/pypi/django-curtail-uuid

Brightcells 9 years ago
parent
commit
6e77deb909
5 changed files with 8 additions and 22 deletions
  1. 2 2
      account/admin.py
  2. 2 2
      account/views.py
  3. 3 2
      photo/views.py
  4. 1 0
      requirements.txt
  5. 0 16
      utils/uuid_utils.py

+ 2 - 2
account/admin.py

@@ -5,7 +5,7 @@ from django.contrib.auth.hashers import make_password
5 5
 
6 6
 from account.models import LensmanInfo, LensmanLoginLogInfo, UserInfo, UserLoginLogInfo
7 7
 
8
-from utils.uuid_utils import curtailUUID
8
+from curtail_uuid import CurtailUUID
9 9
 
10 10
 
11 11
 class LensmanInfoAdmin(admin.ModelAdmin):
@@ -16,7 +16,7 @@ class LensmanInfoAdmin(admin.ModelAdmin):
16 16
 
17 17
     def save_model(self, request, obj, form, change):
18 18
         if not obj.lensman_id:
19
-            obj.lensman_id = curtailUUID(LensmanInfo, 'lensman_id')
19
+            obj.lensman_id = CurtailUUID.uuid(LensmanInfo, 'lensman_id')
20 20
         if obj.password:
21 21
             obj.encryption = make_password(obj.password, None, 'pbkdf2_sha256')
22 22
             obj.password = None

+ 2 - 2
account/views.py

@@ -10,8 +10,8 @@ from account.models import LensmanInfo, UserInfo, UserLoginLogInfo
10 10
 from account.serializers import UserSerializer, GroupSerializer, LensmanInfoSerializer, UserInfoSerializer
11 11
 
12 12
 from utils.ip_utils import ip_addr
13
-from utils.uuid_utils import curtailUUID
14 13
 
14
+from curtail_uuid import CurtailUUID
15 15
 from TimeConvert import TimeConvert as tc
16 16
 
17 17
 
@@ -65,7 +65,7 @@ def user_signup_api(request):
65 65
         })
66 66
 
67 67
     user = UserInfo.objects.create(
68
-        user_id=curtailUUID(UserInfo, 'user_id'),
68
+        user_id=CurtailUUID.uuid(UserInfo, 'user_id'),
69 69
         username=username,
70 70
         password=make_password(password, None, 'pbkdf2_sha256'),
71 71
         user_status=UserInfo.ACTIVATED,

+ 3 - 2
photo/views.py

@@ -12,9 +12,10 @@ from account.models import LensmanInfo
12 12
 from photo.models import UUIDInfo, PhotosInfo
13 13
 from photo.serializers import PhotosInfoSerializer
14 14
 
15
-from utils.uuid_utils import curtailUUID
16 15
 from utils.watermark_utils import watermark_wrap
17 16
 
17
+from curtail_uuid import CurtailUUID
18
+
18 19
 import os
19 20
 import shortuuid
20 21
 
@@ -23,7 +24,7 @@ def uuid_init(request):
23 24
     num = int(request.GET.get('num', 1000))
24 25
 
25 26
     for i in xrange(num):
26
-        UUIDInfo.objects.create(uuid=curtailUUID(UUIDInfo))
27
+        UUIDInfo.objects.create(uuid=CurtailUUID.uuid(UUIDInfo))
27 28
 
28 29
     return JsonResponse({
29 30
         'status': 200,

+ 1 - 0
requirements.txt

@@ -2,6 +2,7 @@ CodeConvert==2.0.3
2 2
 Django==1.8.4
3 3
 MySQL-python==1.2.5
4 4
 TimeConvert==1.1.3
5
+django-curtail-uuid==1.0.0
5 6
 django-multidomain==1.1.4
6 7
 django-shortuuidfield==0.1.3
7 8
 djangorestframework==3.3.1

+ 0 - 16
utils/uuid_utils.py

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