From 9636d4a6767f49384d5c386bc3f1142c88b90613 Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Tue, 13 Aug 2013 14:13:24 +0800 Subject: cloned from 'bitbucket', 2013/08/13 --- 97suifangqa/apps/profile/__init__.py | 0 97suifangqa/apps/profile/backends.py | 25 ++++++ 97suifangqa/apps/profile/forms.py | 4 + 97suifangqa/apps/profile/image.py | 97 +++++++++++++++++++++++ 97suifangqa/apps/profile/models.py | 144 +++++++++++++++++++++++++++++++++++ 97suifangqa/apps/profile/storage.py | 21 +++++ 97suifangqa/apps/profile/urls.py | 9 +++ 97suifangqa/apps/profile/utils.py | 19 +++++ 97suifangqa/apps/profile/views.py | 30 ++++++++ 9 files changed, 349 insertions(+) create mode 100644 97suifangqa/apps/profile/__init__.py create mode 100644 97suifangqa/apps/profile/backends.py create mode 100644 97suifangqa/apps/profile/forms.py create mode 100644 97suifangqa/apps/profile/image.py create mode 100644 97suifangqa/apps/profile/models.py create mode 100644 97suifangqa/apps/profile/storage.py create mode 100644 97suifangqa/apps/profile/urls.py create mode 100644 97suifangqa/apps/profile/utils.py create mode 100644 97suifangqa/apps/profile/views.py (limited to '97suifangqa/apps/profile') diff --git a/97suifangqa/apps/profile/__init__.py b/97suifangqa/apps/profile/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/97suifangqa/apps/profile/backends.py b/97suifangqa/apps/profile/backends.py new file mode 100644 index 0000000..8903805 --- /dev/null +++ b/97suifangqa/apps/profile/backends.py @@ -0,0 +1,25 @@ +#-*- coding: utf-8 -*- + +from django.contrib.auth.models import User + +class EmailOrUsernameModelBackend(object): + + def authenticate(self, username=None, password=None): + if '@' in username: + kwargs = {'email': username} + else: + kwargs = {'username': username} + try: + user = User.objects.get(**kwargs) + if user.check_password(password): + return user + except User.DoesNotExist: + pass + return None + + def get_user(self, user_id): + try: + return User.objects.get(pk=user_id) + except User.DoesNotExist: + pass + return None \ No newline at end of file diff --git a/97suifangqa/apps/profile/forms.py b/97suifangqa/apps/profile/forms.py new file mode 100644 index 0000000..1d3aed5 --- /dev/null +++ b/97suifangqa/apps/profile/forms.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from django import forms +from django.contrib.auth.forms import UserCreationForm diff --git a/97suifangqa/apps/profile/image.py b/97suifangqa/apps/profile/image.py new file mode 100644 index 0000000..b5dd550 --- /dev/null +++ b/97suifangqa/apps/profile/image.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +""" + 图片处理函数 +""" +import os +import time + +from hashlib import md5 +from django.conf import settings +from os import mkdir, path as _path + +try: + from PIL import Image, ImageOps, ImageDraw +except: + import Image, ImageOps, ImageDraw + + +def rm_avatar_thumb(object_id, avatar_link): + name, ext = _path.splitext(avatar_link) + try: + fn = generat_location(object_id, ext, 200) + os.remove(fn) + except: + pass + + +def _mkdir(dirname): + """ + 遍历创建文件夹 + """ + index = [] + initial = 0 + for i in range(dirname.count('/')): + initial = dirname.find('/', initial, len(dirname)) + index.insert(len(index), initial) + initial += 1 + for j in index[1:]: + _dir = dirname[:j] + if _dir and not _path.exists(_dir): + mkdir(_dir) + + +def generat_dir_and_fn(uid, flag): + root = settings.MEDIA_ROOT + fn = md5('%s' % uid).hexdigest() + d1 = fn[-2:] + d2 = fn[-4:-2] + dirname = "%s%s/%s/%s/" % (root, flag, d1, d2) + return dirname, fn + + +def generat_location(uid, ext, size, flag): + """ + 获取文件路径 + """ + fmt = "%s%s_%s%s" + dirname, fn = generat_dir_and_fn(uid, flag) + _mkdir(dirname) + if not ext or \ + ext == '.': + ext = '.jpg' + return fmt % (dirname, fn, size, ext) + + +def crop(image, object_id, size=100, mask_img=None, flag="cache", **kwargs): + """ + 截取图片 + """ + _size = (size, size) + path = image.path + root, filename = _path.split(path) + name, ext = _path.splitext(filename) + + original = Image.open(open(path, 'rb')) + + # 保存为圆形缩略图 + """ + mask = Image.new('L', _size, 0) + draw = ImageDraw.Draw(mask) + draw.ellipse((0, 0) + _size, fill=255) + thumb = ImageOps.fit(original, mask.size, centering=(0.5, 0.5)) + thumb.putalpha(mask) + """ + try: + if mask_img: + mask = Image.open(mask_img).convert('L') + thumb = ImageOps.fit(original, _size, centering=(0.5, 0.5)) + thumb.putalpha(mask) + else: thumb = ImageOps.fit(original, _size, Image.ANTIALIAS) + + thumb_path = generat_location(object_id, ext, size, flag) + if not _path.exists(thumb_path): + thumb.save(thumb_path) + except: + thumb_path = path + + return thumb_path.replace(settings.MEDIA_ROOT, settings.MEDIA_URL) \ No newline at end of file diff --git a/97suifangqa/apps/profile/models.py b/97suifangqa/apps/profile/models.py new file mode 100644 index 0000000..2168f39 --- /dev/null +++ b/97suifangqa/apps/profile/models.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- + +from django.db import models +from django.contrib import admin +from django.contrib.auth.models import User +from django.contrib.contenttypes.models import ContentType +from django.contrib.contenttypes import generic + +from .storage import OverwriteStorage +from .utils import avatar_by_user +from .image import crop + + +class Profile(models.Model): + + gender_choices = ( + (0, u"男"), + (1, u"女") + ) + + education_choices = ( + (0, u"高中"), + (1, u"大专"), + (2, u"本科"), + (3, u"硕士"), + (4, u"博士")) + + user = models.OneToOneField(User, null=True, blank=True) + name = models.CharField(u"用户名", max_length=20, null=True, blank=True) + avatar = models.ImageField(u"头像", upload_to="uploads/avatar/", storage=OverwriteStorage()) + education = models.IntegerField(u"学历", choices=education_choices) + email = models.EmailField(u"邮箱", primary_key=True) + gender = models.IntegerField(u"性别", choices=gender_choices, default=0) + user_level= models.IntegerField(u"等级", default=0) + medicines = models.ManyToManyField("medicine.Medicine", related_name="users", verbose_name= u"药物", null=True, blank=True) + hospital = models.ForeignKey("location.Hospital", related_name="patients", verbose_name= u"医院", null=True, blank=True) + + class Meta: + verbose_name_plural = u"用户信息" + + def __unicode__(self): + return "< Profile : %s >" % self.id + + def save(self, exist=False, *args, **kwargs): + # 保存 + + if self.id: + exist = True + if not exist and not self.avatar: + # 自动生成头像 + self.avatar = avatar_by_user(self.user) + super(Profile, self).save(*args, **kwargs) + + def thumbnail(self, size=100): + # 头像截图 + return crop(self.avatar, self.user.id, size, flag="user") + +class UserHospitalItem(models.Model): + + created_at = models.DateTimeField(u"创建时间", auto_now_add=True) + user = models.ForeignKey(User, verbose_name=u"用户", null=True, blank=True) + hospital = models.ManyToManyField("location.Hospital", related_name='userhospitalitems', verbose_name=u"就诊医院", null=True, blank=True) + + class Meta: + verbose_name_plural=u"就诊医院记录" + + def __unicode__(self): + return "< UserHospitalItem: %s>" % self.id + + +class UserReadingLog(models.Model): + + created_at = models.DateTimeField(u"创建时间", auto_now_add=True) + user = models.ForeignKey(User, verbose_name=u"用户", null=True, blank=True) + #sciblog = models.ForeignKey('blog.SciBlog', related_name="readinglogs", verbose_name=u"文章") + sciblog = models.TextField(u"文章") #TODO:修改成真正的sciblog外键 + readevent = models.ManyToManyField('ReadEvent', related_name="readinglogs", verbose_name=u"阅读事件", null=True, blank=True) + + class Meta: + verbose_name_plural=u"用户医学文章阅读记录" + + def __unicode__(self): + return "< UserReadingLog: %s >" % self.id + + +class ReadEvent(models.Model): + + type_choices = ( + (0, "isUnd"), + (1, "fav"), + (2, "ask"), + (3, "note"),) + + type = models.IntegerField(u"类型", choices=type_choices, default=0) + + content_type = models.ForeignKey(ContentType, null=True, blank=True) # 将ReadEvent作为GenericForeignKey + object_id = models.PositiveIntegerField(null=True, blank=True) + content_object = generic.GenericForeignKey("content_type", "object_id") + + class Meta: + verbose_name_plural=u"文章阅读事件" + + def __unicode__(self): + return "< ReadEvent: %s >" % self.id + + +class Noting(models.Model): + + content = models.TextField(u"内容") # TODO: 完善代码,确保能输入中文 + user = models.ForeignKey(User, verbose_name=u"用户", null=True, blank=True) + + content_type = models.ForeignKey(ContentType, null=True, blank=True) # 将ReadEvent作为GenericForeignKey + object_id = models.PositiveIntegerField(null=True, blank=True) + content_object = generic.GenericForeignKey("content_type", "object_id") + + class Meta: + verbose_name_plural=u"记笔记" + + def __unicode__(self): + return "< Noting: %s >" % self.id + + +class UserLevelLog(models.Model): + + value = models.FloatField(u"获得经验值") + created_at = models.DateTimeField(u"创建时间", auto_now_add=True) + user = models.ForeignKey(User, verbose_name=u"用户", null=True, blank=True) + + class Meta: + verbose_name_plural=u"用户等级记录" + + def __unicode__(self): + return "< UserLevelLog: %s >" % self.id + + + +admin.site.register([ + Profile, + UserHospitalItem, + UserReadingLog, + ReadEvent, + Noting, + UserLevelLog, + ]) diff --git a/97suifangqa/apps/profile/storage.py b/97suifangqa/apps/profile/storage.py new file mode 100644 index 0000000..f5069fc --- /dev/null +++ b/97suifangqa/apps/profile/storage.py @@ -0,0 +1,21 @@ +#-*- coding: utf-8 -*- +""" + 文件存储 +""" +import os +import time +import random + +from django.core.files.storage import FileSystemStorage + +class OverwriteStorage(FileSystemStorage): + + def _save(self, name, content): + if self.exists(name): + self.delete(name) + ext = os.path.splitext(name)[1] + d = os.path.dirname(name) + fn = time.strftime("%Y%m%d%H%M%S") + fn = fn + "_%d" % random.randint(0,1000) + name = os.path.join(d, fn + ext) + return super(OverwriteStorage, self)._save(name, content) \ No newline at end of file diff --git a/97suifangqa/apps/profile/urls.py b/97suifangqa/apps/profile/urls.py new file mode 100644 index 0000000..cbc453d --- /dev/null +++ b/97suifangqa/apps/profile/urls.py @@ -0,0 +1,9 @@ +from django.conf.urls import patterns, url + +from .views import * + +urlpatterns = patterns('', + url(r'^login/?$', login, name = "login"), + url(r'^logout/?$', logout, name = "logout"), + url(r'^signup/?$', signup, name = "signup"), + ) diff --git a/97suifangqa/apps/profile/utils.py b/97suifangqa/apps/profile/utils.py new file mode 100644 index 0000000..27067d5 --- /dev/null +++ b/97suifangqa/apps/profile/utils.py @@ -0,0 +1,19 @@ +#-*- coding: utf-8 -*- + +import random + +from django.conf import settings + + +def avatar_by_user(user): + """ + 生成头像 + """ + from django.core.files.images import ImageFile + + _avatar_path = "%s/avatars/%s.png" % (settings.MEDIA_ROOT, random.randint(1,22)) + + _avatar = ImageFile(open(_avatar_path)) + user.profile.avatar = _avatar + user.profile.save() + return user.profile \ No newline at end of file diff --git a/97suifangqa/apps/profile/views.py b/97suifangqa/apps/profile/views.py new file mode 100644 index 0000000..c41e62b --- /dev/null +++ b/97suifangqa/apps/profile/views.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +from django.http import HttpResponse, HttpResponseRedirect +from django.conf import settings +from django.shortcuts import render +from django.contrib.auth.views import login, logout +from django.contrib.auth import login as auth_login + +from .forms import UserCreationForm + + + +def signup(request): + u''' + 用户注册 + ''' + if request.user.is_authenticated(): + return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL) + + if request.method == 'POST': + form = UserCreationForm(request.POST) + if form.is_valid(): + user = form.save() + return HttpResponseRedirect(request.REQUEST.get('next')) + else: + form = UserCreationForm() + + return render(request, 'registration/signup.html', + locals()) + -- cgit v1.2.2