首页
美图
服务
付费
树洞
云主机
推荐
邻居
支付
开发
书单
更多
我的足迹
罗盘时钟
圈小猫
工作打分
给我留言
本站统计
推荐
M商城
欣悦云店
txt阅读器
VPS监控
证书监控
网址导航
在线工具
Search
1
docker和docker-compose一键安装脚本
5,065 阅读
2
采用Prometheus+Grafana 监控H3C交换机状态
4,502 阅读
3
WooCommerce对接第三方支付插件开发
4,179 阅读
4
grafana的Dashboard面板添加阈值报警
2,853 阅读
5
docker下运行grafana和grafana Image Renderer
2,778 阅读
虚拟化
数据库
运维
基础知识
监控预警
数据展示
运维工具
web安全
系统服务
开发
python
php
java
shell
go
项目
博客
电商
工具
娱乐
综合
VPS相关
规范文档
知识总结
经验分享
读书笔记
关于
Search
标签搜索
django
python
运维工具
支付对接
电商平台
Joe主题
docker
wordpress
woocommerce
支付通道
zabbix
蓝鲸智云
运维
grafana
监控
运维知识
typecho
php
mysql
nginx
行云流水
累计撰写
324
篇文章
累计收到
360
条评论
首页
栏目
虚拟化
数据库
运维
基础知识
监控预警
数据展示
运维工具
web安全
系统服务
开发
python
php
java
shell
go
项目
博客
电商
工具
娱乐
综合
VPS相关
规范文档
知识总结
经验分享
读书笔记
关于
页面
美图
服务
树洞
云主机
邻居
支付
书单
给我留言
本站统计
推荐
M商城
txt阅读器
网址导航
搜索到
28
篇与
的结果
2024-10-24
基于Django的录音管理系统的开发总结
前言安卓手机默认打开了通话录音功能,几年下来积攒了上千条录音,一直懒得清理。最近写了一个管理系统,将所有录音文件导入。进行可视化分析,给自己几年打的所有电话生成一份报告。更直观的展示自己的通讯情况。{card-default label="统计" width="80%"}{/card-default}开发过程录音文件的管理通过django框架开发,主要功能点有通讯录管理、录音文件管理、录音文件转文字管理。转文字通过调用腾讯api完成,将结果保存到数据库,便于查询。可视化模块通过grafana直接读取mysql数据实现。模型类的设计模型类包括三种,Contact类、CallRecord类和RecordResult类。Contact类存储通讯录信息,包含名称和号码等class Contact(models.Model): number = models.CharField(max_length=15,verbose_name='电话号码') # 电话号码 name = models.CharField(blank=True,null=True,max_length=100,verbose_name='联系人') # 联系人姓名 # 新增的类型字段 TYPE_CHOICES = [ ('family', '亲朋'), ('work', '工作'), ('promotion', '推广'), ('taxi', '滴滴'), ('service', '客服'), ('delivery', '快递'), ] contact_type = models.CharField( max_length=10, choices=TYPE_CHOICES, verbose_name='类型', default='promotion', # 默认值为'亲朋' ) def __str__(self): return self.number class Meta: verbose_name = '通讯录' verbose_name_plural = '通讯录'CallRecord类用于存储音频文件、状态、音频转文字的任务信息等class CallRecord(models.Model): phone_number = models.ForeignKey(Contact, related_name='call_records', on_delete=models.CASCADE) # 电话号码外键 call_time = models.DateTimeField(verbose_name='时间') # 通话时间 recording_file = models.CharField(max_length=255, blank=True, null=True, verbose_name='文件名') # 录音文件名 notes = models.TextField(blank=True, null=True, verbose_name='备注') # 备注 task_id = models.CharField(max_length=255, blank=True, null=True, verbose_name='任务id') # 任务ID,可为空 # 状态字段的选择 STATUS_CHOICES = [ ('未处理', '未处理'), # Unprocessed ('处理中', '处理中'), # Processing ('已完成', '已完成'), # Completed ] status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='未处理', verbose_name='状态') # 状态,默认值为 '未处理' def __str__(self): return f"{self.phone_number.number} - {self.call_time}" # 返回通话记录的字符串表示 class Meta: verbose_name = '通话录音' # 该模型的单数名称 verbose_name_plural = '通话录音' # 该模型的复数名称RecordResult用于管理存储音频转文字的结果等信息class RecordResult(models.Model): call_record = models.OneToOneField(CallRecord, related_name='record_result', on_delete=models.CASCADE) # 与 CallRecord 的一对一关系 # 录音时长,单位为秒 duration = models.PositiveIntegerField(verbose_name='时长') # 时长,正整数 # 错误信息,可以为空 error_message = models.TextField(blank=True, null=True, verbose_name='错误') # 错误信息,可为空值 # 文本结果,可以为空 text_result = models.TextField(blank=True, null=True, verbose_name='全文') # 文本结果,可为空 # 文本大纲,可以为空 text_outline = models.TextField(blank=True, null=True, verbose_name='大纲') # 文本大纲,可为空 # 标签,可以为空 tags = models.CharField(max_length=255, blank=True, null=True, verbose_name='标签') # 标签,最多 255 字符,可以为空 # 备注,可以为空 notes = models.TextField(blank=True, null=True, verbose_name='备注') # 备注,可为空 def __str__(self): return f"{self.call_record.phone_number.number} - {self.duration}" class Meta: verbose_name = '通话文本' # 模型的单数名称 verbose_name_plural = '通话文本' # 模型的复数名称接口设计录音文件入库、文本结果处理等任务过程中用到的各种接口。# 防止重复入库的接口 class CheckRecordingFile(APIView): def post(self, request): # 获取file_name参数 file_name = request.data.get('file_name') if not file_name: return Response({"error": "file_name is required"}, status=status.HTTP_400_BAD_REQUEST) # 查询CallRecord中是否有这个file_name record_exists = CallRecord.objects.filter(recording_file=file_name).exists() # 根据查询结果返回True或False if record_exists: return Response({"exists": True}, status=status.HTTP_200_OK) else: return Response({"exists": False}, status=status.HTTP_200_OK) #录音在线播放用到的接口 class AudioList(APIView): def get(self, request): mediaList = [] # 获取URL查询字符串中的rid参数 rid = request.query_params.get('rid') cid = request.query_params.get('cid') if rid: mediaList = CallRecord.objects.filter(id=rid) if cid: contact = Contact.objects.get(id=cid) mediaList = CallRecord.objects.filter(phone_number=contact) arr = [] #倒序 for item in mediaList[::-1]: # 随机1-10专辑封面图片 sui_num = random.randint(1, 10) #构建 arr.append({ 'id': item.id, 'title': f"{item.record_result.id} - {item.phone_number.number} - {item.call_time}", 'singer': f"{item.phone_number.name}", 'songUrl': f"{settings.MEDIA_URL}{urllib.parse.quote(item.recording_file)}", 'imageUrl': '/static/images/' + str(sui_num) + '.png', }) return Response({'list': arr}, status=status.HTTP_201_CREATED)录音文件同步手机中的通讯录音会自动传输到家庭nfs,管理系统会单独启动一个循环任务去nfs拉取音频文件入库并创建音频转文字任务。import subprocess import time from datetime import datetime # 定义需要执行的命令 commands = [ "mkdir -p /tmp/lxnfs", "mount -t smbfs //189xxxxx805:zhixxxx6@192.168.1.150/7460088 /tmp/lxnfs", "cp -n /tmp/lxnfs/来自ADT-AN00的手机备份/文件夹备份/* /Users/xinei/project/audioman/data/files/ || true", "umount /tmp/lxnfs" ] # 定义一个函数来执行这些命令 def run_commands(): for command in commands: try: # 执行每条命令 subprocess.run(command, shell=True, check=True) print(f"执行成功: {command}") except subprocess.CalledProcessError as e: print(f"命令执行失败: {command}\n错误信息: {e}") # 主循环,每小时检查一次时间 while True: current_time = datetime.now() # 只在 20:00 到 24:00 之间执行命令 if current_time.hour >= 20 and current_time.hour < 23: print(f"当前时间: {current_time}. 在允许的时间范围内,执行命令。") run_commands() else: print(f"当前时间: {current_time}. 不在允许的时间范围内,跳过执行。") # 等待 1 小时再检查时间 time.sleep(3600)录音文件转文字录音文件写入数据库后,默认状态为待处理。另一个脚本会自动扫描未处理的记录,然后自动创建处理任务。# 监控指定目录 def monitor_directory(path): observer = None event_handler = MyEventHandler() try: while True: current_time = datetime.now() # 只在20:00到24:00之间执行监控 if current_time.hour >= 20 and current_time.hour < 24: if observer is None: # 只有在 observer 没有启动时才创建新的观察者 observer = Observer() observer.schedule(event_handler, path, recursive=False) observer.start() print(f"当前时间: {current_time}. 启动监控。") else: if observer is not None: observer.stop() observer.join() # 等待线程停止 observer = None # 将 observer 置为 None,以便后续创建新的实例 print(f"当前时间: {current_time}. 停止监控。") time.sleep(3600) # 每小时检查一次时间 time.sleep(600) # 每次监控状态保持10分钟,然后再循环检查 except KeyboardInterrupt: if observer is not None: observer.stop() observer.join() if __name__ == "__main__": directory_to_watch = "/files/" # 替换为你要监控的目录 monitor_directory(directory_to_watch)可视化过程可视化通过grafana实现。直接链接mysql数据库,通过sql查询数据并返回,具体页面如开头所示。完整项目代码获取【统计分析】基于Django开发的录音管理系统源码
2024年10月24日
17 阅读
0 评论
0 点赞
2023-08-25
Django后台列表的自定义过滤条件显示
Django后台列表的自定义过滤条件显示,记录太多。只显示有用的信息。
2023年08月25日
172 阅读
0 评论
0 点赞
2023-08-25
Django的celery通过配置添加周期性任务
以前都是通过函数,动态添加周期性任务。新的项目比较简单。直接在项目启动时加载周期性任务,加载后也不变动。
2023年08月25日
142 阅读
0 评论
0 点赞
2023-08-08
Django之图片上传与展示
之前开发的系统需要用户自己上传截图用于审核,记录一下Django从前端接收图片到后台保存处理展示的整个过程
2023年08月08日
452 阅读
0 评论
0 点赞
2023-08-05
Django模版函数用法
Django使用模板渲染数据,返回的数据有时候需要处理。用到了templatetags模版函数,记录使用方法。
2023年08月05日
237 阅读
0 评论
0 点赞
2023-07-15
利用Django和hAdmin快速开发管理系统(三)
在第一篇文件分享了登录页的开发。在用户登录之前,需要注册。注册时,除了系统默认的user表。还有自动创建扩展信息条目。用到了Django的信号机制。
2023年07月15日
222 阅读
0 评论
0 点赞
2023-07-15
Django默认管理后台开发的一些技巧总结(二)
上一篇文章分享了后台列表的自定义按钮,并通过按钮做一些操作。本文分享自定义上传文件页面,接收文件后并处理的过程。
2023年07月15日
186 阅读
0 评论
0 点赞
2023-07-15
Django默认管理后台开发的一些技巧总结(一)
Django在开发管理系统的过程中,给客户用的前台配合hAdmin很快就搞好了。默认后台平时自己用,也没那么多讲究。这次要给别人用。就需要考虑权限,还有一些样式啥的。需要花点心思美化一下。
2023年07月15日
409 阅读
0 评论
0 点赞
2023-07-15
利用Django和hAdmin快速开发管理系统(二)
前言上篇文章分享了如何创建登录页,登录页实际是一个表单提交的过程。本文分享信息的展示,也就是table。拿其中账号余额的变动页面作为示例。{card-default label="交易记录展示" width="80%"}{/card-default}过程去数据库中查找信息,返回给前端模板渲染路由配置customer目录下的urls.py中配置from django.conf.urls import url from customer import views urlpatterns = [ url(r'^login/$', views.customer_login, name='customer'), #登录 url(r'^usertrans/$', views.customer_user_transaction, name='customer'), #账号交易记录 ]模板渲染模板渲染函数写在目录下的views.py内@login_required(login_url='/customer/login/') def customer_user_transaction(request): """ 账号交易记录 """ user = request.user blancerecords = BalanceRecord.objects.filter(owner=user).all() content = { 'user':user, 'records': blancerecords, 'recard_types': RECORDB_TYPES, 'recard_status': R_STATUS_CHOICES, } return render(request, 'usertrans.html', content)html模板html模板主要用来调整样式,展示数据{% load static %} <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> - 交易查询</title> <meta name="keywords" content=""> <meta name="description" content=""> <link rel="shortcut icon" href="{% static 'favicon.ico' %}"> <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet"> <link href="{% static 'css/font-awesome.css' %}" rel="stylesheet"> <link href="{% static 'css/animate.css' %}" rel="stylesheet"> <link href="{% static 'css/style.css' %}" rel="stylesheet"> <!-- Data Tables --> <link href="{% static 'css/plugins/dataTables/dataTables.bootstrap.css' %}" rel="stylesheet"> </head> <body class="gray-bg"> <div class="wrapper wrapper-content animated fadeInRight"> <div class="row"> <div class="col-sm-12"> <div class="ibox float-e-margins"> <div class="ibox-title"> <h5>账号流水 <small>账号余额的变动、划拨到卡、手续费等</small></h5> </div> <div class="ibox-content"> <table class="table table-striped table-bordered table-hover dataTables-example"> <thead> <tr> <th>序号</th> <th>时间</th> <th>变动类型</th> <th>金额(USD)</th> <th>状态</th> </tr> </thead> <tbody> {% for record in records %} <tr class="{% cycle 'gradeX' 'gradeC' %}"> <td>{{ forloop.counter }}</td> <td>{{ record.created_at }}</td> <td class="center"> {% for choice in recard_types %} {% if record.record_type == choice.0 %} {{ choice.1 }} {% endif %} {% endfor %} </td> <td class="center"> {% if record.record_type < 6 %} <span class="badge badge-info">加</span> {% else %} <span class="badge badge-danger">减</span> {% endif %} {{ record.amount }} </td> <td class="center"> {% for choice in recard_status %} {% if record.status == choice.0 %} {{ choice.1 }} {% endif %} {% endfor %} </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </div> </div> <!-- 全局js --> <script src="{% static 'js/jquery.min.js' %}"></script> <script src="{% static 'js/bootstrap.min.js' %}"></script> <script src="{% static 'js/plugins/jeditable/jquery.jeditable.js' %}"></script> <!-- Data Tables --> <script src="{% static 'js/plugins/dataTables/jquery.dataTables.js' %}"></script> <script src="{% static 'js/plugins/dataTables/dataTables.bootstrap.js' %}"></script> <!-- 自定义js --> <script src="{% static 'js/content.js' %}"></script> <!-- Page-Level Scripts --> <script> $(document).ready(function () { $('.dataTables-example').dataTable( { "order": [[0, 'desc']] } ); }); </script> </body> </html>
2023年07月15日
162 阅读
0 评论
0 点赞
2023-07-14
利用Django和hAdmin快速开发管理系统(一)
最近有一个小的应用需要配套一套管理系统给客户使用。使客户用来管理自己的积分余额,充值和查询历史记录啥的。也没啥其他要求,只想最快速的写出来。就用自己比较熟悉的Django,Django本身带后台给自己用。在写一个稍微好看点的给客户用。找了一大圈,发现了hAdmin。刚刚合适。
2023年07月14日
328 阅读
0 评论
0 点赞
1
2
3