1
+"""
2
+WSGI config for pai2 project.
3
+
4
+It exposes the WSGI callable as a module-level variable named ``application``.
5
+
6
+For more information on this file, see
7
+https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
8
+"""
9
+
10
+import os
11
+
12
+from django.core.wsgi import get_wsgi_application
13
+
14
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pai2.settings")
15
+
16
+application = get_wsgi_application()

+ 9 - 0
pep8.sh

@@ -0,0 +1,9 @@
1
+#!/bin/bash
2
+
3
+# Ignoring autogenerated files
4
+#  -- Migration directories
5
+# Ignoring error codes
6
+#  -- E128 continuation line under-indented for visual indent
7
+#  -- E501 line too long
8
+
9
+pep8 --exclude=migrations --ignore=E128,E501 .

+ 0 - 0
photo/__init__.py


+ 13 - 0
photo/admin.py

@@ -0,0 +1,13 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.contrib import admin
4
+
5
+from photo.models import PhotosInfo
6
+
7
+
8
+class PhotosInfoAdmin(admin.ModelAdmin):
9
+    list_display = ('lensman_id', 'session_id', 'photo_id', 'photo_path', 'status', 'created_at', 'updated_at')
10
+    list_filter = ('lensman_id', 'status')
11
+
12
+
13
+admin.site.register(PhotosInfo, PhotosInfoAdmin)

+ 34 - 0
photo/migrations/0001_initial.py

@@ -0,0 +1,34 @@
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
+    ]
11
+
12
+    operations = [
13
+        migrations.CreateModel(
14
+            name='PhotosInfo',
15
+            fields=[
16
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
17
+                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
18
+                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
19
+                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
20
+                ('lesman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lesman_id', db_index=True)),
21
+                ('session_id', models.CharField(max_length=255, blank=True, help_text='\u7167\u7247\u7ec4\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='session_id', db_index=True)),
22
+                ('photo_id', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_id', db_index=True)),
23
+                ('photo_path', models.CharField(help_text='\u7167\u7247\u5b58\u653e\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)),
24
+            ],
25
+            options={
26
+                'verbose_name': 'photosinfo',
27
+                'verbose_name_plural': 'photosinfo',
28
+            },
29
+        ),
30
+        migrations.AlterIndexTogether(
31
+            name='photosinfo',
32
+            index_together=set([('lesman_id', 'session_id')]),
33
+        ),
34
+    ]

+ 27 - 0
photo/migrations/0002_auto_20151113_1419.py

@@ -0,0 +1,27 @@
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', '0001_initial'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='photosinfo',
16
+            name='lensman_id',
17
+            field=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),
18
+        ),
19
+        migrations.AlterIndexTogether(
20
+            name='photosinfo',
21
+            index_together=set([('lensman_id', 'session_id')]),
22
+        ),
23
+        migrations.RemoveField(
24
+            model_name='photosinfo',
25
+            name='lesman_id',
26
+        ),
27
+    ]

+ 0 - 0
photo/migrations/__init__.py


+ 39 - 0
photo/models.py

@@ -0,0 +1,39 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.conf import settings
4
+from django.db import models
5
+from django.utils.translation import ugettext_lazy as _
6
+
7
+from pai2.basemodels import CreateUpdateMixin
8
+
9
+
10
+class PhotosInfo(CreateUpdateMixin):
11
+    lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)
12
+    session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True)
13
+    photo_id = models.CharField(_(u'photo_id'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True)
14
+    photo_path = models.CharField(_(u'photo_path'), max_length=255, blank=True, null=True, help_text=u'照片存放路径')
15
+
16
+    class Meta:
17
+        verbose_name = _('photosinfo')
18
+        verbose_name_plural = _('photosinfo')
19
+        index_together = [
20
+            ['lensman_id', 'session_id'],
21
+        ]
22
+
23
+    def __unicode__(self):
24
+        return u'{0.pk}'.format(self)
25
+
26
+    @property
27
+    def photo_url(self):
28
+        return u'{0}/media/{1}'.format(settings.DOMAIN, self.photo_path) if self.photo_path else ''
29
+
30
+    def _data(self):
31
+        return {
32
+            'pk': self.pk,
33
+            'lensman_id': self.lensman_id,
34
+            'session_id': self.session_id,
35
+            'photo_id': self.photo_id,
36
+            'photo_url': self.photo_url,
37
+        }
38
+
39
+    data = property(_data)

+ 10 - 0
photo/serializers.py

@@ -0,0 +1,10 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from photo.models import PhotosInfo
4
+from rest_framework import serializers
5
+
6
+
7
+class PhotosInfoSerializer(serializers.HyperlinkedModelSerializer):
8
+    class Meta:
9
+        model = PhotosInfo
10
+        fields = ('lensman_id', 'session_id', 'photo_id', 'photo_path', 'created_at')

+ 3 - 0
photo/tests.py

@@ -0,0 +1,3 @@
1
+from django.test import TestCase
2
+
3
+# Create your tests here.

+ 0 - 0
photo/urls.py


+ 71 - 0
photo/views.py

@@ -0,0 +1,71 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from django.core.files.storage import default_storage
4
+from django.http import JsonResponse
5
+
6
+from rest_framework import viewsets
7
+
8
+from account.models import LensmanInfo
9
+from photo.models import PhotosInfo
10
+from photo.serializers import PhotosInfoSerializer
11
+
12
+import os
13
+
14
+
15
+# [How to do a PUT request with curl?](http://stackoverflow.com/questions/13782198/how-to-do-a-put-request-with-curl)
16
+# Unfortunately, the -T is no substitute for -X PUT if you want to specify parameters with -d or -F.
17
+# -T sends the content of a file via PUT. To achieve the GET after a redirect, add the parameter --location
18
+#
19
+# -F, --form <name=content>
20
+#               (HTTP)  This  lets  curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data
21
+#               using the Content-Type multipart/form-data according to RFC 2388. This enables uploading of binary files  etc.  To  force  the
22
+#               'content'  part  to  be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file
23
+#               name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file  upload,
24
+#               while the < makes a text field and just get the contents for that text field from a file.
25
+#
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
27
+def upload_photo(request):
28
+    lensman_id = request.POST.get('lensman_id', '')
29
+    session_id = request.POST.get('session_id', '')
30
+    photo_id = request.POST.get('photo_id', '')
31
+
32
+    photo = request.FILES.get('photo', '')
33
+
34
+    if not (lensman_id and session_id and photo_id and photo):
35
+        return JsonResponse({
36
+            'status': 400,
37
+            'message': u'参数错误',
38
+        })
39
+
40
+    try:
41
+        LensmanInfo.objects.get(lensman_id=lensman_id)
42
+    except LensmanInfo.DoesNotExist:
43
+        return JsonResponse({
44
+            'status': 400,
45
+            'message': u'参数错误',
46
+        })
47
+
48
+    _, extension = os.path.splitext(photo.name)
49
+    photo_path = 'photo/{0}/{1}/{2}{3}'.format(lensman_id, session_id, photo_id, extension)
50
+
51
+    if default_storage.exists(photo_path):
52
+        default_storage.delete(photo_path)
53
+    default_storage.save(photo_path, photo)
54
+
55
+    photo, created = PhotosInfo.objects.get_or_create(
56
+        lensman_id=lensman_id,
57
+        session_id=session_id,
58
+        photo_id=photo_id,
59
+        photo_path=photo_path
60
+    )
61
+
62
+    return JsonResponse({
63
+        'status': 200,
64
+        'message': u'照片上传成功',
65
+        'data': photo.data,
66
+    })
67
+
68
+
69
+class PhotoInfoViewSet(viewsets.ModelViewSet):
70
+    queryset = PhotosInfo.objects.all().order_by('-created_at')
71
+    serializer_class = PhotosInfoSerializer

+ 12 - 0
requirements.txt

@@ -0,0 +1,12 @@
1
+CodeConvert==2.0.3
2
+Django==1.8.4
3
+MySQL-python==1.2.5
4
+TimeConvert==1.0.7
5
+django-shortuuidfield==0.1.3
6
+djangorestframework==3.3.1
7
+ipdb==0.8.1
8
+ipython==4.0.0
9
+pep8==1.6.2
10
+pillow==2.9.0
11
+pytz==2015.7
12
+uWSGI==2.0.11.1

Kodo/kodo - Gogs: Go Git Service

1 Commits (75ab3f509788aa92700c96590bb0e6534fa2cb4b)

Autor SHA1 Mensagem Data
  Brightcells 7a17d0fb90 add api wxpay & add redis relative 9 anos atrás