diff --git a/update/migrations/0011_alter_release_options_alter_release_status.py b/update/migrations/0011_alter_release_options_alter_release_status.py new file mode 100644 index 0000000..6f9ee85 --- /dev/null +++ b/update/migrations/0011_alter_release_options_alter_release_status.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.7 on 2024-01-09 00:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0010_clientrelease_client_ver'), + ] + + operations = [ + migrations.AlterModelOptions( + name='release', + options={'ordering': ['id', 'version', 'short_ver', 'status', 'update_time'], 'verbose_name': '鼎新版本', 'verbose_name_plural': '鼎新版本'}, + ), + migrations.AlterField( + model_name='release', + name='status', + field=models.CharField(default='0', help_text='版本状态, 0-无效,1-开发,2-测试,3-上线', max_length=10, verbose_name='版本状态'), + ), + ] diff --git a/update/migrations/0012_alter_release_options.py b/update/migrations/0012_alter_release_options.py new file mode 100644 index 0000000..a267635 --- /dev/null +++ b/update/migrations/0012_alter_release_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.7 on 2024-01-09 01:09 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0011_alter_release_options_alter_release_status'), + ] + + operations = [ + migrations.AlterModelOptions( + name='release', + options={'verbose_name': '鼎新版本', 'verbose_name_plural': '鼎新版本'}, + ), + ] diff --git a/update/migrations/0013_cinemauser_pinyin.py b/update/migrations/0013_cinemauser_pinyin.py new file mode 100644 index 0000000..0bab31d --- /dev/null +++ b/update/migrations/0013_cinemauser_pinyin.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-01-09 09:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0012_alter_release_options'), + ] + + operations = [ + migrations.AddField( + model_name='cinemauser', + name='pinyin', + field=models.CharField(default='', help_text='用户名拼音', max_length=30, verbose_name='用户名拼音'), + ), + ] diff --git a/update/migrations/0014_updatecommand_run_num_updatecommand_ver.py b/update/migrations/0014_updatecommand_run_num_updatecommand_ver.py new file mode 100644 index 0000000..85e3e55 --- /dev/null +++ b/update/migrations/0014_updatecommand_run_num_updatecommand_ver.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.7 on 2024-01-09 09:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0013_cinemauser_pinyin'), + ] + + operations = [ + migrations.AddField( + model_name='updatecommand', + name='run_num', + field=models.IntegerField(default=0, help_text='执行命令的顺', verbose_name='执行命令的顺'), + ), + migrations.AddField( + model_name='updatecommand', + name='ver', + field=models.CharField(default='', help_text='支持此命令的版本', max_length=2000, verbose_name='支持此命令的版本'), + ), + ] diff --git a/update/models.py b/update/models.py index d165a93..c17b2bb 100644 --- a/update/models.py +++ b/update/models.py @@ -32,6 +32,7 @@ class CinemaUser(models.Model): """ id = models.AutoField(primary_key=True) username = models.CharField(verbose_name='用户名', max_length=30, null=False, help_text='用户名') + pinyin = models.CharField(verbose_name='用户名拼音', max_length=30, null=False, default='', help_text='用户名拼音') is_delete = models.BooleanField(verbose_name='是否删除', default=False, help_text='是否删除') def __str__(self): @@ -42,6 +43,7 @@ class CinemaUser(models.Model): verbose_name_plural = '影院使用人' db_table = 'update_cinema_user' + class Release(BaseModels): """ 鼎新版本表 @@ -50,7 +52,7 @@ class Release(BaseModels): version = models.CharField(verbose_name='鼎新版本', max_length=100, null=False, help_text='鼎新版本') short_ver = models.CharField(verbose_name='短版本号', max_length=100, null=False, help_text='短版本号') status = models.CharField(verbose_name='版本状态', max_length=10, null=False, - help_text='版本状态, 0-开发, 1-测试, 2上线', default='0') + help_text='版本状态, 0-无效,1-开发,2-测试,3-上线', default='0') def __str__(self): return self.version @@ -67,11 +69,13 @@ class ClientRelease(BaseModels): """ id = models.AutoField(primary_key=True) origin_name = models.CharField(verbose_name='原始名称', max_length=500, null=False, help_text='smb上的名称') - client_ver = models.CharField(verbose_name='客户端版本', max_length=100, null=False, default='', help_text='客户端版本') + client_ver = models.CharField(verbose_name='客户端版本', max_length=100, null=False, default='', + help_text='客户端版本') main_ver = models.CharField(verbose_name='主版本', max_length=100, null=False, default='', help_text='主版本') sub_ver = models.CharField(verbose_name='小版本', max_length=10, null=False, default='', help_text='小版本') upload_name = models.CharField(verbose_name='上传名称', max_length=200, null=False, help_text='上传名称') - client_type = models.CharField(verbose_name='类型', max_length=10, default='test', help_text='类型 test 测试 prd 线上') + client_type = models.CharField(verbose_name='类型', max_length=10, default='test', + help_text='类型 test 测试 prd 线上') is_delete = models.BooleanField(verbose_name='是否有效', default=False, help_text='是否有效') def __str__(self): @@ -90,7 +94,10 @@ class UpdateCommand(BaseModels): id = models.AutoField(primary_key=True) desc = models.CharField(verbose_name='命令作用描述', max_length=200, null=False, help_text='命令作用描述') command = models.CharField(verbose_name='需执行的命令', max_length=2000, null=False, help_text='需执行的命令') - process = models.CharField(verbose_name='执行顺序', max_length=20, default='setup', help_text='执行顺序 setup 对比数据库前执行 teardown 对比数据库后执行') + ver = models.CharField(verbose_name='支持此命令的版本', max_length=2000, null=False, default='', help_text='支持此命令的版本') + process = models.CharField(verbose_name='执行顺序', max_length=20, default='setup', + help_text='执行顺序 setup 对比数据库前执行 teardown 对比数据库后执行') + run_num = models.IntegerField(verbose_name='执行命令的顺', null=False, default=0, help_text='执行命令的顺') is_sys = models.BooleanField(verbose_name='系统命令', default=False, help_text='系统命令,默认执行前台不展示') is_checked = models.BooleanField(verbose_name='默认勾选', default=False, help_text='前台页面默认是否勾选') is_delete = models.BooleanField(verbose_name='是否有效', default=True, help_text='是否有效') diff --git a/update/serializers.py b/update/serializers.py index e730e85..fc983b6 100644 --- a/update/serializers.py +++ b/update/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers, fields -from update.models import Cinema +from update.models import * class CinemaSerializer(serializers.ModelSerializer): @@ -7,4 +7,35 @@ class CinemaSerializer(serializers.ModelSerializer): class Meta: model = Cinema - fields = ('id', 'name', 'ip', 'zz_num', 'inner_id', 'db_user', 'db_pwd', 'sys_ver', 'client_ver', 'update_time') + fields = ( + 'id', 'name', 'ip', 'zz_num', 'inner_id', 'db_user', 'db_pwd', 'sys_ver', 'client_ver', 'user', + 'update_time') + + +class CinemaUserSerializer(serializers.ModelSerializer): + class Meta: + model = CinemaUser + fields = ('id', 'username', 'is_delete', 'pinyin') + + +class ReleaseSerializer(serializers.ModelSerializer): + class Meta: + model = Release + fields = ('id', 'version', 'short_ver', 'status') + + +class ClientReleaseSerializer(serializers.ModelSerializer): + update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S') + + class Meta: + model = ClientRelease + fields = ('id', 'origin_name', 'client_ver', 'main_ver', 'sub_ver', 'upload_name', 'client_type', 'is_delete', + 'update_time') + + +class UpdateCommandSerializer(serializers.ModelSerializer): + update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S') + + class Meta: + model = UpdateCommand + fields = ('id', 'desc', 'command', 'process', 'is_sys', 'is_checked', 'is_delete', 'update_time') diff --git a/update/urls.py b/update/urls.py index b3bfed9..62a257e 100644 --- a/update/urls.py +++ b/update/urls.py @@ -17,16 +17,20 @@ Including another URLconf from django.urls import path, re_path, include from update import views from rest_framework.routers import DefaultRouter +from update.views import * router = DefaultRouter() router.register('cinema', views.CinemaViewSet, 'cinema') +router.register('user', views.CinemaUserViewSet, 'cinema_user') urlpatterns = [ # path('cinema/search/', views.CinemaSearchAPIView.as_view()), path('', include(router.urls)), - + path('get_git_version/', get_git_version), + path('get_operation_cmd/', get_operation_cmd), # re_path(r'^cinema/search/ip/(?P[0-9.]*?)/version/(?P[\S]*?)/$', views.CinemaSearchAPIView.as_view()) - + # 测试用的接口 + path('git/write_git_version_to_db/', write_git_version_to_db) ] -# &version=(?P[\S]*?) \ No newline at end of file +# &version=(?P[\S]*?) diff --git a/update/utils/cmd_extcute.py b/update/utils/cmd_extcute.py index 2eb6f7f..e653b2a 100644 --- a/update/utils/cmd_extcute.py +++ b/update/utils/cmd_extcute.py @@ -4,37 +4,37 @@ from django.db.models import Q class UpdateCommandUtil: - def __init__(self, cinema_ip): - self.cinema_config = {'hostname': cinema_ip, 'port': 22, 'username': 'root', 'password': 'cine123456'} + def __init__(self): self.client = paramiko.SSHClient() self.model = UpdateCommand - def connect(self): + def connect(self, cinema_ip): + cinema_config = {'hostname': cinema_ip, 'port': 22, 'username': 'root', 'password': 'cine123456'} self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - self.client.connect(**self.cinema_config) + self.client.connect(**cinema_config) def disconnect(self): self.client.close() def get_all_cmd(self): - return self.model.objects.filter(is_delete='0').order_by(id).all() + return self.model.objects.filter(is_delete=False).order_by('id').all() def get_sys_cmd(self): - return self.model.objects.filter(Q(is_delete='0') & Q(is_sys='1')).order_by(id).all() + return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=True)).order_by('id').all() def get_no_sys_cmd(self): - return self.model.objects.exclude(Q(is_delete='0') & Q(is_sys='0')).order_by(id).all() + return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False)).order_by('id').all() def get_no_sys_setup_cmd(self): - return self.model.objects.filter(Q(is_delete='0') & Q(is_sys='0') & Q(process='setup')).order_by(id).all() + return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False) & Q(process='setup')).order_by('id').all() def get_no_sys_teardown_cmd(self): - return self.model.objects.filter(Q(is_delete='0') & Q(is_sys='0') & Q(process='teardown')).order_by(id).all() + return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False) & Q(process='teardown')).order_by('id').all() def get_checked_cmd(self, cmd_list): sys_result = self.get_sys_cmd() checked_setup_result = self.model.objects.filter( - Q(is_delete='0') & Q(id__in=cmd_list) & Q(process='setup')).order_by(id).all() + Q(is_delete='0') & Q(id__in=cmd_list) & Q(process='setup')).order_by('id').all() checked_teardown_result = self.model.objects.filter( Q(is_delete='0') & Q(id__in=cmd_list) & Q(process='teardown')).order_by( id).all() diff --git a/update/utils/get_version.py b/update/utils/get_version.py index 520c726..0e8e077 100644 --- a/update/utils/get_version.py +++ b/update/utils/get_version.py @@ -1,7 +1,7 @@ import pymysql from pymysql.cursors import DictCursor from multiprocessing import cpu_count -from update.models import Cinema +from update.models import Cinema, CinemaUser import queue import threading from django.utils import timezone @@ -51,7 +51,7 @@ class GetVersion(object): return else: cinema_config = q.get() - sql_str = "SELECT cs.cinema_id, cs.cinema_name, cs.cinema_num, cv.server_version, cv.client_version FROM cinema_set cs LEFT JOIN cinema_version cv ON 1=1;;" + sql_str = "SELECT cs.cinema_id, cs.cinema_name, cs.cinema_num, cv.server_version, cv.client_version FROM cinema_set cs LEFT JOIN cinema_version cv ON 1=1;" ip = cinema_config.get('ip') db_config = { 'host': ip, diff --git a/update/utils/git_util.py b/update/utils/git_util.py index bdcb5d3..f1ea3c4 100644 --- a/update/utils/git_util.py +++ b/update/utils/git_util.py @@ -4,11 +4,12 @@ import os import shutil import hashlib import pymysql +from dingxin_toolbox_drf import settings class GitUtil: def __init__(self): - self.local_path = '../../dx/code' + self.local_path = os.path.join(settings.BASE_DIR, r'dx\code') self.db_config = { 'host': 'home.rogersun.cn', 'user': 'dingxin', @@ -34,24 +35,26 @@ class GitUtil: release = [] for remote in local_repo.remotes: for ref in remote.refs: - release.append(ref) + release.append(ref.name) saved_release = Release.objects.all() + saved_release_version_list = [rel['version'] for rel in saved_release] + for rel in release: - if rel in saved_release['version']: + if rel in saved_release_version_list: pass else: data = { 'version': rel, - 'short_ver': rel[:-8] if '_Release' in rel else rel, + 'short_ver': rel[7:-8] if '_Release' in rel else rel, 'status': '0' } - Release.objects.update(**data) + Release.objects.create(**data) # 复制文cine.sql到本地路径 def copy_cine_sql(self, _release): self.checkout_release(_release) - short_ver = 'cine_' + self.get_short_version(_release) + short_ver = 'cine_' + self.get_short_version_by_release(_release) org_path = os.path.join(self.local_path, 'install/cine.sql') target_path = os.path.join(self.local_path, 'sql/' + _release + '.sql') if os.path.exists(target_path): @@ -80,7 +83,7 @@ class GitUtil: def write_sql(self, _release): if os.path.exists(sql_path := os.path.join(self.local_path, 'sql/' + _release + '.sql')): - short_ver = 'cine_' + self.get_short_version(_release) + short_ver = 'cine_' + self.get_short_version_by_release(_release) execute_sql_list = [f'DROP DATABASE IF EXISTS {short_ver};'] with open(sql_path, 'r', encoding='utf-8') as sql_file: content = sql_file.read() @@ -102,14 +105,19 @@ class GitUtil: # 获取数据库名称 def get_db_name(self, _release): - return 'cine_' + self.get_short_version(_release) + return 'cine_' + self.get_short_version_by_release(_release) # 获取端短版本号 @staticmethod - def get_short_version(_release): + def get_short_version_by_release(_release): data = Release.objects.filter(version=_release).first() return data.short_version + @staticmethod + def get_short_version(): + data = Release.objects.exclude(status='0').order_by('-short_ver').all() + return [{'version': r.version, 'short_ver': r.short_ver, 'status': r.status} for r in data] + @staticmethod def get_md5(path): with open(path, "rb") as f: @@ -125,4 +133,4 @@ class GitUtil: if __name__ == '__main__': git_util = GitUtil() - git_util.clone() + # git_util.clone() diff --git a/update/views.py b/update/views.py index 01bef95..ebcbfa7 100644 --- a/update/views.py +++ b/update/views.py @@ -4,7 +4,7 @@ from rest_framework import viewsets, permissions, status, filters from rest_framework.filters import OrderingFilter from update.models import Cinema -from update.serializers import CinemaSerializer +from update.serializers import * from rest_framework.views import APIView from rest_framework.response import Response from rest_framework_extensions.cache.mixins import CacheResponseMixin @@ -14,6 +14,8 @@ from django_filters.rest_framework import DjangoFilterBackend from django.core.cache import cache from update.utils.get_version import GetVersion from rest_framework.decorators import action +from update.utils.git_util import GitUtil +from update.utils.cmd_extcute import UpdateCommandUtil # CacheResponseMixin 一定要放第一位 @@ -30,7 +32,7 @@ class CinemaViewSet(CacheResponseMixin, viewsets.ModelViewSet): serializer_class = CinemaSerializer permission_classes = (permissions.IsAuthenticated,) filter_backends = (filters.SearchFilter, DjangoFilterBackend, OrderingFilter) - ordering_fields = ('ip', ) + ordering_fields = ('ip',) search_fields = ('sys_ver',) # filter_fields = ('ip',) filterset_fields = ('ip',) @@ -45,6 +47,11 @@ class CinemaViewSet(CacheResponseMixin, viewsets.ModelViewSet): return Response(serializer.data) +class CinemaUserViewSet(CacheResponseMixin, viewsets.ModelViewSet): + queryset = CinemaUser.objects.order_by('pinyin').all() + serializer_class = CinemaUserSerializer + + # class CinemaSearchAPIView(APIView, CacheResponseMixin): # @method_decorator(cache_page(60 * 5)) # def get(self, request, *args, **kwargs): @@ -54,3 +61,23 @@ class CinemaViewSet(CacheResponseMixin, viewsets.ModelViewSet): # Q(ip__contains=query_params.get('ip')) & Q(sys_ver__icontains=query_params.get('version'))) # serializer = CinemaSerializer(instance=query_data, many=True) # return Response(serializer.data, status=status.HTTP_200_OK) + +def get_git_version(request): + git_util = GitUtil() + git_ver = git_util.get_short_version() + serializer = ReleaseSerializer(instance=git_ver, many=True) + return JsonResponse(serializer.data, safe=False) + + +def get_operation_cmd(request): + update_cmd = UpdateCommandUtil() + no_sys_cmd = update_cmd.get_no_sys_cmd() + serializer = UpdateCommandSerializer(instance=no_sys_cmd, many=True) + return JsonResponse(serializer.data, safe=False) + + +# 测试用接口 +def write_git_version_to_db(request): + git_util = GitUtil() + git_util.set_release_to_db() + return JsonResponse({'result': 'success'})