From 4500c0b32f19a241a6c8dbee264bdcab371aa8f4 Mon Sep 17 00:00:00 2001 From: liangliangyy Date: Tue, 7 Mar 2023 18:14:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=91=BD=E5=90=8D=E9=94=99=E8=AF=AF=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=90=8C=E6=AD=A5=E5=A4=B4=E5=83=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 - accounts/migrations/0001_initial.py | 49 +++++++ blog/management/commands/sync_user_avatar.py | 28 ++-- blog/migrations/0001_initial.py | 137 +++++++++++++++++++ comments/migrations/0001_initial.py | 38 +++++ djangoblog/utils.py | 9 +- oauth/admin.py | 6 +- oauth/migrations/0001_initial.py | 57 ++++++++ oauth/models.py | 9 +- oauth/oauthmanager.py | 44 ++++-- oauth/views.py | 14 +- owntracks/migrations/0001_initial.py | 31 +++++ servermanager/migrations/0001_initial.py | 45 ++++++ 13 files changed, 426 insertions(+), 43 deletions(-) create mode 100644 accounts/migrations/0001_initial.py create mode 100644 blog/migrations/0001_initial.py create mode 100644 comments/migrations/0001_initial.py create mode 100644 oauth/migrations/0001_initial.py create mode 100644 owntracks/migrations/0001_initial.py create mode 100644 servermanager/migrations/0001_initial.py diff --git a/.gitignore b/.gitignore index 92ad5afdd..5d6eb23e1 100644 --- a/.gitignore +++ b/.gitignore @@ -67,8 +67,6 @@ target/ # virtualenv venv/ -migrations/ -!migrations/__init__.py collectedstatic/ djangoblog/whoosh_index/ google93fd32dbd906620a.html diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py new file mode 100644 index 000000000..d2fbcab51 --- /dev/null +++ b/accounts/migrations/0001_initial.py @@ -0,0 +1,49 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +import django.contrib.auth.models +import django.contrib.auth.validators +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='BlogUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('nickname', models.CharField(blank=True, max_length=100, verbose_name='昵称')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('source', models.CharField(blank=True, max_length=100, verbose_name='创建来源')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': '用户', + 'verbose_name_plural': '用户', + 'ordering': ['-id'], + 'get_latest_by': 'id', + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + ] diff --git a/blog/management/commands/sync_user_avatar.py b/blog/management/commands/sync_user_avatar.py index a236e1420..dd59f0c8a 100644 --- a/blog/management/commands/sync_user_avatar.py +++ b/blog/management/commands/sync_user_avatar.py @@ -1,26 +1,38 @@ +import requests from django.core.management.base import BaseCommand -from django.template.context_processors import static +from django.templatetags.static import static from djangoblog.utils import save_user_avatar from oauth.models import OAuthUser +from oauth.oauthmanager import get_manager_by_type class Command(BaseCommand): help = 'sync user avatar' + def test_picture(self, url): + try: + if requests.get(url, timeout=2).status_code == 200: + return True + except: + pass + def handle(self, *args, **options): - static_url = static("avatar/") - users = OAuthUser.objects.filter(picture__isnull=False).exclude( - picture__istartswith=static_url).all() - self.stdout.write('开始同步{count}个用户头像'.format(count=len(users))) + static_url = static("../") + users = OAuthUser.objects.filter(picture__isnull=False).all() + self.stdout.write(f'开始同步{len(users)}个用户头像') for u in users: - self.stdout.write('开始同步:{id}'.format(id=u.nikename)) + self.stdout.write(f'开始同步:{u.nickname}') url = u.picture + if self.test_picture(url): + continue + if url.startswith(static_url): + manage = get_manager_by_type(u.type) + url = manage.get_picture(u.metadata) url = save_user_avatar(url) if url: self.stdout.write( - '结束同步:{id}.url:{url}'.format( - id=u.nikename, url=url)) + f'结束同步:{u.nickname}.url:{url}') u.picture = url u.save() self.stdout.write('结束同步') diff --git a/blog/migrations/0001_initial.py b/blog/migrations/0001_initial.py new file mode 100644 index 000000000..3d391b628 --- /dev/null +++ b/blog/migrations/0001_initial.py @@ -0,0 +1,137 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import mdeditor.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='BlogSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sitename', models.CharField(default='', max_length=200, verbose_name='网站名称')), + ('site_description', models.TextField(default='', max_length=1000, verbose_name='网站描述')), + ('site_seo_description', models.TextField(default='', max_length=1000, verbose_name='网站SEO描述')), + ('site_keywords', models.TextField(default='', max_length=1000, verbose_name='网站关键字')), + ('article_sub_length', models.IntegerField(default=300, verbose_name='文章摘要长度')), + ('sidebar_article_count', models.IntegerField(default=10, verbose_name='侧边栏文章数目')), + ('sidebar_comment_count', models.IntegerField(default=5, verbose_name='侧边栏评论数目')), + ('article_comment_count', models.IntegerField(default=5, verbose_name='文章页面默认显示评论数目')), + ('show_google_adsense', models.BooleanField(default=False, verbose_name='是否显示谷歌广告')), + ('google_adsense_codes', models.TextField(blank=True, default='', max_length=2000, null=True, verbose_name='广告内容')), + ('open_site_comment', models.BooleanField(default=True, verbose_name='是否打开网站评论功能')), + ('beiancode', models.CharField(blank=True, default='', max_length=2000, null=True, verbose_name='备案号')), + ('analyticscode', models.TextField(default='', max_length=1000, verbose_name='网站统计代码')), + ('show_gongan_code', models.BooleanField(default=False, verbose_name='是否显示公安备案号')), + ('gongan_beiancode', models.TextField(blank=True, default='', max_length=2000, null=True, verbose_name='公安备案号')), + ], + options={ + 'verbose_name': '网站配置', + 'verbose_name_plural': '网站配置', + }, + ), + migrations.CreateModel( + name='Links', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='链接名称')), + ('link', models.URLField(verbose_name='链接地址')), + ('sequence', models.IntegerField(unique=True, verbose_name='排序')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否显示')), + ('show_type', models.CharField(choices=[('i', '首页'), ('l', '列表页'), ('p', '文章页面'), ('a', '全站'), ('s', '友情链接页面')], default='i', max_length=1, verbose_name='显示类型')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ], + options={ + 'verbose_name': '友情链接', + 'verbose_name_plural': '友情链接', + 'ordering': ['sequence'], + }, + ), + migrations.CreateModel( + name='SideBar', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='标题')), + ('content', models.TextField(verbose_name='内容')), + ('sequence', models.IntegerField(unique=True, verbose_name='排序')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否启用')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ], + options={ + 'verbose_name': '侧边栏', + 'verbose_name_plural': '侧边栏', + 'ordering': ['sequence'], + }, + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='标签名')), + ('slug', models.SlugField(blank=True, default='no-slug', max_length=60)), + ], + options={ + 'verbose_name': '标签', + 'verbose_name_plural': '标签', + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='Category', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('name', models.CharField(max_length=30, unique=True, verbose_name='分类名')), + ('slug', models.SlugField(blank=True, default='no-slug', max_length=60)), + ('index', models.IntegerField(default=0, verbose_name='权重排序-越大越靠前')), + ('parent_category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='父级分类')), + ], + options={ + 'verbose_name': '分类', + 'verbose_name_plural': '分类', + 'ordering': ['-index'], + }, + ), + migrations.CreateModel( + name='Article', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('title', models.CharField(max_length=200, unique=True, verbose_name='标题')), + ('body', mdeditor.fields.MDTextField(verbose_name='正文')), + ('pub_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='发布时间')), + ('status', models.CharField(choices=[('d', '草稿'), ('p', '发表')], default='p', max_length=1, verbose_name='文章状态')), + ('comment_status', models.CharField(choices=[('o', '打开'), ('c', '关闭')], default='o', max_length=1, verbose_name='评论状态')), + ('type', models.CharField(choices=[('a', '文章'), ('p', '页面')], default='a', max_length=1, verbose_name='类型')), + ('views', models.PositiveIntegerField(default=0, verbose_name='浏览量')), + ('article_order', models.IntegerField(default=0, verbose_name='排序,数字越大越靠前')), + ('show_toc', models.BooleanField(default=False, verbose_name='是否显示toc目录')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')), + ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='分类')), + ('tags', models.ManyToManyField(blank=True, to='blog.tag', verbose_name='标签集合')), + ], + options={ + 'verbose_name': '文章', + 'verbose_name_plural': '文章', + 'ordering': ['-article_order', '-pub_time'], + 'get_latest_by': 'id', + }, + ), + ] diff --git a/comments/migrations/0001_initial.py b/comments/migrations/0001_initial.py new file mode 100644 index 000000000..61d1e539f --- /dev/null +++ b/comments/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('blog', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('body', models.TextField(max_length=300, verbose_name='正文')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否显示')), + ('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='文章')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')), + ('parent_comment', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='上级评论')), + ], + options={ + 'verbose_name': '评论', + 'verbose_name_plural': '评论', + 'ordering': ['-id'], + 'get_latest_by': 'id', + }, + ), + ] diff --git a/djangoblog/utils.py b/djangoblog/utils.py index fa5597e65..9d722e308 100644 --- a/djangoblog/utils.py +++ b/djangoblog/utils.py @@ -177,17 +177,10 @@ def save_user_avatar(url): :param url:头像url :return: 本地路径 ''' - setting = get_blog_setting() logger.info(url) try: basedir = os.path.join(settings.STATICFILES, 'avatar') - - imgname = url.split('/')[-1] - if imgname: - path = f'{basedir}/{imgname}' - if os.path.exists(path): - os.remove(path) rsp = requests.get(url, timeout=2) if rsp.status_code == 200: if not os.path.exists(basedir): @@ -203,7 +196,7 @@ def save_user_avatar(url): return static('avatar/' + save_filename) except Exception as e: logger.error(e) - return url + return static('blog/img/avatar.png') def delete_sidebar_cache(): diff --git a/oauth/admin.py b/oauth/admin.py index ec0e3c997..57eab5f52 100644 --- a/oauth/admin.py +++ b/oauth/admin.py @@ -9,17 +9,17 @@ class OAuthUserAdmin(admin.ModelAdmin): - search_fields = ('nikename', 'email') + search_fields = ('nickname', 'email') list_per_page = 20 list_display = ( 'id', - 'nikename', + 'nickname', 'link_to_usermodel', 'show_user_image', 'type', 'email', ) - list_display_links = ('id', 'nikename') + list_display_links = ('id', 'nickname') list_filter = ('author', 'type',) readonly_fields = [] diff --git a/oauth/migrations/0001_initial.py b/oauth/migrations/0001_initial.py new file mode 100644 index 000000000..3aa3e0317 --- /dev/null +++ b/oauth/migrations/0001_initial.py @@ -0,0 +1,57 @@ +# Generated by Django 4.1.7 on 2023-03-07 09:53 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='OAuthConfig', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('weibo', '微博'), ('google', '谷歌'), ('github', 'GitHub'), ('facebook', 'FaceBook'), ('qq', 'QQ')], default='a', max_length=10, verbose_name='类型')), + ('appkey', models.CharField(max_length=200, verbose_name='AppKey')), + ('appsecret', models.CharField(max_length=200, verbose_name='AppSecret')), + ('callback_url', models.CharField(default='http://www.baidu.com', max_length=200, verbose_name='回调地址')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否显示')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ], + options={ + 'verbose_name': 'oauth配置', + 'verbose_name_plural': 'oauth配置', + 'ordering': ['-created_time'], + }, + ), + migrations.CreateModel( + name='OAuthUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('openid', models.CharField(max_length=50)), + ('nickname', models.CharField(max_length=50, verbose_name='昵称')), + ('token', models.CharField(blank=True, max_length=150, null=True)), + ('picture', models.CharField(blank=True, max_length=350, null=True)), + ('type', models.CharField(max_length=50)), + ('email', models.CharField(blank=True, max_length=50, null=True)), + ('metadata', models.TextField(blank=True, null=True)), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + ('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')), + ], + options={ + 'verbose_name': 'oauth用户', + 'verbose_name_plural': 'oauth用户', + 'ordering': ['-created_time'], + }, + ), + ] diff --git a/oauth/models.py b/oauth/models.py index 08cdd6f28..ff82607d0 100644 --- a/oauth/models.py +++ b/oauth/models.py @@ -14,17 +14,17 @@ class OAuthUser(models.Model): null=True, on_delete=models.CASCADE) openid = models.CharField(max_length=50) - nikename = models.CharField(max_length=50, verbose_name='昵称') + nickname = models.CharField(max_length=50, verbose_name='昵称') token = models.CharField(max_length=150, null=True, blank=True) picture = models.CharField(max_length=350, blank=True, null=True) type = models.CharField(blank=False, null=False, max_length=50) email = models.CharField(max_length=50, null=True, blank=True) - matedata = models.TextField(null=True, blank=True) + metadata = models.TextField(null=True, blank=True) created_time = models.DateTimeField('创建时间', default=now) last_mod_time = models.DateTimeField('修改时间', default=now) def __str__(self): - return self.nikename + return self.nickname class Meta: verbose_name = 'oauth用户' @@ -55,8 +55,7 @@ class OAuthConfig(models.Model): def clean(self): if OAuthConfig.objects.filter( - type=self.type).exclude( - id=self.id).count(): + type=self.type).exclude(id=self.id).count(): raise ValidationError(_(self.type + '已经存在')) def __str__(self): diff --git a/oauth/oauthmanager.py b/oauth/oauthmanager.py index 16dc55c29..339e0429b 100644 --- a/oauth/oauthmanager.py +++ b/oauth/oauthmanager.py @@ -51,6 +51,10 @@ def get_access_token_by_code(self, code): def get_oauth_userinfo(self): pass + @abstractmethod + def get_picture(self, metadata): + pass + def do_get(self, url, params, headers=None): rsp = requests.get(url=url, params=params, headers=headers) logger.info(rsp.text) @@ -122,9 +126,9 @@ def get_oauth_userinfo(self): try: datas = json.loads(rsp) user = OAuthUser() - user.matedata = rsp + user.metadata = rsp user.picture = datas['avatar_large'] - user.nikename = datas['screen_name'] + user.nickname = datas['screen_name'] user.openid = datas['id'] user.type = 'weibo' user.token = self.access_token @@ -136,6 +140,10 @@ def get_oauth_userinfo(self): logger.error('weibo oauth error.rsp:' + rsp) return None + def get_picture(self, metadata): + datas = json.loads(metadata) + return datas['avatar_large'] + class GoogleOauthManager(BaseOauthManager): AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth' @@ -197,9 +205,9 @@ def get_oauth_userinfo(self): datas = json.loads(rsp) user = OAuthUser() - user.matedata = rsp + user.metadata = rsp user.picture = datas['picture'] - user.nikename = datas['name'] + user.nickname = datas['name'] user.openid = datas['sub'] user.token = self.access_token user.type = 'google' @@ -211,6 +219,10 @@ def get_oauth_userinfo(self): logger.error('google oauth error.rsp:' + rsp) return None + def get_picture(self, metadata): + datas = json.loads(metadata) + return datas['picture'] + class GitHubOauthManager(BaseOauthManager): AUTH_URL = 'https://github.com/login/oauth/authorize' @@ -268,11 +280,11 @@ def get_oauth_userinfo(self): datas = json.loads(rsp) user = OAuthUser() user.picture = datas['avatar_url'] - user.nikename = datas['name'] + user.nickname = datas['name'] user.openid = datas['id'] user.type = 'github' user.token = self.access_token - user.matedata = rsp + user.metadata = rsp if 'email' in datas and datas['email']: user.email = datas['email'] return user @@ -281,6 +293,10 @@ def get_oauth_userinfo(self): logger.error('github oauth error.rsp:' + rsp) return None + def get_picture(self, metadata): + datas = json.loads(metadata) + return datas['avatar_url'] + class FaceBookOauthManager(BaseOauthManager): AUTH_URL = 'https://www.facebook.com/v2.10/dialog/oauth' @@ -337,11 +353,11 @@ def get_oauth_userinfo(self): rsp = self.do_get(self.API_URL, params) datas = json.loads(rsp) user = OAuthUser() - user.nikename = datas['name'] + user.nickname = datas['name'] user.openid = datas['id'] user.type = 'facebook' user.token = self.access_token - user.matedata = rsp + user.metadata = rsp if 'email' in datas and datas['email']: user.email = datas['email'] if 'picture' in datas and datas['picture'] and datas['picture']['data'] and datas['picture']['data']['url']: @@ -351,6 +367,10 @@ def get_oauth_userinfo(self): logger.error(e) return None + def get_picture(self, metadata): + datas = json.loads(metadata) + return str(datas['picture']['data']['url']) + class QQOauthManager(BaseOauthManager): AUTH_URL = 'https://graph.qq.com/oauth2.0/authorize' @@ -425,17 +445,21 @@ def get_oauth_userinfo(self): logger.info(rsp) obj = json.loads(rsp) user = OAuthUser() - user.nikename = obj['nickname'] + user.nickname = obj['nickname'] user.openid = openid user.type = 'qq' user.token = self.access_token - user.matedata = rsp + user.metadata = rsp if 'email' in obj: user.email = obj['email'] if 'figureurl' in obj: user.picture = str(obj['figureurl']) return user + def get_picture(self, metadata): + datas = json.loads(metadata) + return str(datas['figureurl']) + @cache_decorator(expiration=100 * 60) def get_oauth_apps(): diff --git a/oauth/views.py b/oauth/views.py index a15311deb..00ec4c990 100644 --- a/oauth/views.py +++ b/oauth/views.py @@ -72,13 +72,13 @@ def authorize(request): return HttpResponseRedirect(manager.get_authorization_url(nexturl)) user = manager.get_oauth_userinfo() if user: - if not user.nikename or not user.nikename.strip(): - user.nikename = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') + if not user.nickname or not user.nickname.strip(): + user.nickname = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') try: temp = OAuthUser.objects.get(type=type, openid=user.openid) temp.picture = user.picture - temp.matedata = user.matedata - temp.nikename = user.nikename + temp.metadata = user.metadata + temp.nickname = user.nickname user = temp except ObjectDoesNotExist: pass @@ -97,9 +97,9 @@ def authorize(request): author = result[0] if result[1]: try: - get_user_model().objects.get(username=user.nikename) + get_user_model().objects.get(username=user.nickname) except ObjectDoesNotExist: - author.username = user.nikename + author.username = user.nickname else: author.username = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') author.source = 'authorize' @@ -139,7 +139,7 @@ def emailconfirm(request, id, sign): author = result[0] if result[1]: author.source = 'emailconfirm' - author.username = oauthuser.nikename.strip() if oauthuser.nikename.strip( + author.username = oauthuser.nickname.strip() if oauthuser.nickname.strip( ) else "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') author.save() oauthuser.author = author diff --git a/owntracks/migrations/0001_initial.py b/owntracks/migrations/0001_initial.py new file mode 100644 index 000000000..9eee55c06 --- /dev/null +++ b/owntracks/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='OwnTrackLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tid', models.CharField(max_length=100, verbose_name='用户')), + ('lat', models.FloatField(verbose_name='纬度')), + ('lon', models.FloatField(verbose_name='经度')), + ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + ], + options={ + 'verbose_name': 'OwnTrackLogs', + 'verbose_name_plural': 'OwnTrackLogs', + 'ordering': ['created_time'], + 'get_latest_by': 'created_time', + }, + ), + ] diff --git a/servermanager/migrations/0001_initial.py b/servermanager/migrations/0001_initial.py new file mode 100644 index 000000000..bbdbf7759 --- /dev/null +++ b/servermanager/migrations/0001_initial.py @@ -0,0 +1,45 @@ +# Generated by Django 4.1.7 on 2023-03-02 07:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='commands', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=300, verbose_name='命令标题')), + ('command', models.CharField(max_length=2000, verbose_name='命令')), + ('describe', models.CharField(max_length=300, verbose_name='命令描述')), + ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('last_mod_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')), + ], + options={ + 'verbose_name': '命令', + 'verbose_name_plural': '命令', + }, + ), + migrations.CreateModel( + name='EmailSendLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('emailto', models.CharField(max_length=300, verbose_name='收件人')), + ('title', models.CharField(max_length=2000, verbose_name='邮件标题')), + ('content', models.TextField(verbose_name='邮件内容')), + ('send_result', models.BooleanField(default=False, verbose_name='结果')), + ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ], + options={ + 'verbose_name': '邮件发送log', + 'verbose_name_plural': '邮件发送log', + 'ordering': ['-created_time'], + }, + ), + ]