diff --git a/.gitignore b/.gitignore index 25cd33a..593904d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /venv/ .idea -/logs/ \ No newline at end of file +/logs/ +/dx/ diff --git a/reqirement.txt b/reqirement.txt index 36c6f68..552f223 100644 Binary files a/reqirement.txt and b/reqirement.txt differ diff --git a/update/migrations/0004_cinemauser_clientrelease_release_updatecommand.py b/update/migrations/0004_cinemauser_clientrelease_release_updatecommand.py new file mode 100644 index 0000000..1ffc441 --- /dev/null +++ b/update/migrations/0004_cinemauser_clientrelease_release_updatecommand.py @@ -0,0 +1,74 @@ +# Generated by Django 4.2.7 on 2024-01-07 01:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0003_alter_cinema_options_alter_cinema_client_ver_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='CinemaUser', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('username', models.CharField(help_text='用户名', max_length=30, verbose_name='用户名')), + ('is_delete', models.BooleanField(default=False, help_text='是否删除', verbose_name='是否删除')), + ], + options={ + 'verbose_name': '影院使用人', + 'verbose_name_plural': '影院使用人', + 'db_table': 'update_cinema_user', + }, + ), + migrations.CreateModel( + name='ClientRelease', + fields=[ + ('update_time', models.DateTimeField(auto_now=True, help_text='最后更新时间', verbose_name='最后更新时间')), + ('id', models.AutoField(primary_key=True, serialize=False)), + ('origin_name', models.CharField(help_text='smb上的名称', max_length=500, verbose_name='原始名称')), + ('ver_time', models.CharField(help_text='版本发布时间', max_length=100, verbose_name='版本发布时间')), + ('upload_name', models.CharField(help_text='上传名称', max_length=200, verbose_name='上传名称')), + ('is_delete', models.BooleanField(default=True, help_text='是否有效', verbose_name='是否有效')), + ], + options={ + 'verbose_name': '鼎新客户端版本', + 'verbose_name_plural': '鼎新客户端版本', + 'db_table': 'update_client_release', + }, + ), + migrations.CreateModel( + name='Release', + fields=[ + ('update_time', models.DateTimeField(auto_now=True, help_text='最后更新时间', verbose_name='最后更新时间')), + ('id', models.AutoField(primary_key=True, serialize=False)), + ('version', models.CharField(help_text='鼎新版本', max_length=100, verbose_name='鼎新版本')), + ('short_ver', models.CharField(help_text='短版本号', max_length=100, verbose_name='短版本号')), + ('status', models.CharField(default='0', help_text='版本状态, 0-开发, 1-测试, 2上线', max_length=10, verbose_name='版本状态')), + ], + options={ + 'verbose_name': '鼎新版本', + 'verbose_name_plural': '鼎新版本', + 'db_table': 'update_dingxin_release', + }, + ), + migrations.CreateModel( + name='UpdateCommand', + fields=[ + ('update_time', models.DateTimeField(auto_now=True, help_text='最后更新时间', verbose_name='最后更新时间')), + ('id', models.AutoField(primary_key=True, serialize=False)), + ('desc', models.CharField(help_text='命令作用描述', max_length=200, verbose_name='命令作用描述')), + ('command', models.CharField(help_text='需执行的命令', max_length=2000, verbose_name='需执行的命令')), + ('is_sys', models.BooleanField(default=False, help_text='系统命令,默认执行前台不展示', verbose_name='系统命令')), + ('is_checked', models.BooleanField(default=False, help_text='前台页面默认是否勾选', verbose_name='默认勾选')), + ('is_delete', models.BooleanField(default=True, help_text='是否有效', verbose_name='是否有效')), + ], + options={ + 'verbose_name': '升级脚本', + 'verbose_name_plural': '升级脚本', + 'db_table': 'update_command', + }, + ), + ] diff --git a/update/migrations/0005_cinema_user.py b/update/migrations/0005_cinema_user.py new file mode 100644 index 0000000..6b34cc0 --- /dev/null +++ b/update/migrations/0005_cinema_user.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-01-07 01:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0004_cinemauser_clientrelease_release_updatecommand'), + ] + + operations = [ + migrations.AddField( + model_name='cinema', + name='user', + field=models.CharField(help_text='当前使用人', max_length=10, null=True, verbose_name='使用人'), + ), + ] diff --git a/update/models.py b/update/models.py index c5db010..893f9e6 100644 --- a/update/models.py +++ b/update/models.py @@ -15,6 +15,7 @@ class Cinema(BaseModels): db_pwd = models.CharField(verbose_name='影院数据库密码', max_length=50, null=False, help_text='影院数据库密码') sys_ver = models.CharField(verbose_name='鼎新系统版本', max_length=50, null=False, help_text='鼎新系统版本') client_ver = models.CharField(verbose_name='鼎新客户端版本', max_length=50, null=False, help_text='鼎新客户端版本') + user = models.CharField(verbose_name='使用人', max_length=10, null=True, help_text='当前使用人') def __str__(self): return self.ip @@ -23,3 +24,77 @@ class Cinema(BaseModels): verbose_name = '影院信息' verbose_name_plural = '影院信息' db_table = 'update_cinema' + + +class CinemaUser(models.Model): + """ + 鼎新使用人表 + """ + id = models.AutoField(primary_key=True) + username = models.CharField(verbose_name='用户名', max_length=30, null=False, help_text='用户名') + is_delete = models.BooleanField(verbose_name='是否删除', default=False, help_text='是否删除') + + def __str__(self): + return self.username + + class Meta: + verbose_name = '影院使用人' + verbose_name_plural = '影院使用人' + db_table = 'update_cinema_user' + +class Release(BaseModels): + """ + 鼎新版本表 + """ + id = models.AutoField(primary_key=True) + 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') + + def __str__(self): + return self.version + + class Meta: + verbose_name = '鼎新版本' + verbose_name_plural = '鼎新版本' + db_table = 'update_dingxin_release' + + +class ClientRelease(BaseModels): + """ + 鼎新客户端版本 + """ + id = models.AutoField(primary_key=True) + origin_name = models.CharField(verbose_name='原始名称', max_length=500, null=False, help_text='smb上的名称') + ver_time = models.CharField(verbose_name='版本发布时间', max_length=100, null=False, help_text='版本发布时间') + upload_name = models.CharField(verbose_name='上传名称', max_length=200, null=False, help_text='上传名称') + is_delete = models.BooleanField(verbose_name='是否有效', default=True, help_text='是否有效') + + def __str__(self): + return self.upload_name + + class Meta: + verbose_name = '鼎新客户端版本' + verbose_name_plural = '鼎新客户端版本' + db_table = 'update_client_release' + + +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='需执行的命令') + 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='是否有效') + + def __str__(self): + return self.desc + + class Meta: + verbose_name = '升级脚本' + verbose_name_plural = '升级脚本' + db_table = 'update_command' diff --git a/update/utils/git_util.py b/update/utils/git_util.py new file mode 100644 index 0000000..b62962a --- /dev/null +++ b/update/utils/git_util.py @@ -0,0 +1,107 @@ +from git import Repo +from update.models import Release +import os +import shutil +import hashlib +import pymysql + + +class GitUtil: + def __init__(self): + self.local_path = '../../dx/code' + self.db_config = { + 'host': 'home.rogersun.cn', + 'user': 'dingxin', + 'password': 'cine123456', + 'connect_timeout': 5, + } + + # 执行一次 clone代码到本地 + def clone(self): + git_url = 'http://dingxin_readonly:cine123456@172.16.3.3:8081/root/dingxin.git' + Repo.clone_from(git_url, to_path=self.local_path, branch='master') + + # 获取指定版本的最新代码 + def checkout_release(self, _release): + local_repo = Repo(self.local_path) + local_repo.git.checkout(_release) + local_repo.git.pull() + + # 获取版本并写入数据库 + def set_release_to_db(self): + local_repo = Repo(self.local_path) + + release = [] + for remote in local_repo.remotes: + for ref in remote.refs: + release.append(ref) + + saved_release = Release.objects.all() + for rel in release: + if rel in saved_release['version']: + pass + else: + data = { + 'version': rel, + 'short_ver': rel[:-8] if '_Release' in rel else rel, + 'status': '0' + } + Release.objects.update(**data) + + # 复制文cine.sql到本地路径 + def copy_cine_sql(self, _release): + self.checkout_release(_release) + short_ver = 'cine_' + self.get_short_version(_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): + os.remove(target_path) + target_file = open(target_path, 'a', encoding='utf-8') + with open(org_path, 'r', encoding='utf') as f: + lines = f.readlines() + for index, line in enumerate(lines): + if line == 'CREATE DATABASE /*!32312 IF NOT EXISTS*/`cine` /*!40100 DEFAULT CHARACTER SET utf8 */;': + lines[index] = f'CREATE DATABASE /*!32312 IF NOT EXISTS*/`{short_ver}` /*!40100 DEFAULT CHARACTER SET utf8 */;' + if line == 'USE `cine`;': + lines[index] = f'USE `{short_ver}`;' + f.close() + target_file.writelines(lines) + target_file.close() + + # 检查cine.sql是否是最新的 + def check_cine_sql(self, _release): + if sql_path := os.path.exists(os.path.join(self.local_path, 'sql/' + _release + '.sql')): + saved_md5 = self.get_md5(sql_path) + new_md5 = self.get_md5(os.path.join(self.local_path, 'install/cine.sql')) + if saved_md5 == new_md5: + return True + return False + + def write_sql(self, _release): + if sql_path := os.path.exists(os.path.join(self.local_path, 'sql/' + _release + '.sql')): + db_conn = pymysql.Connect(**self.db_config) + db_cursor = db_conn.cursor() + db_cursor.executemany() + + # 获取端短版本号 + @staticmethod + def get_short_version(_release): + data = Release.objects.filter(version=_release).first() + return data.short_version + + @staticmethod + def get_md5(path): + with open(path, "rb") as f: + m = hashlib.md5() # 创建md5对象 + with open(path, 'rb') as fobj: + while True: + data = fobj.read(4096) + if not data: + break + m.update(data) # 更新md5对象 + return m.hexdigest() # 返回md5对象 + + +if __name__ == '__main__': + git_util = GitUtil() + git_util.clone()