admin.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>管理员操作中心-{{rules.count}}条规则</title>
  6. <meta name="description" content="particles.js is a lightweight JavaScript library for creating particles.">
  7. <meta name="author" content="道长" />
  8. <meta name="viewport"
  9. content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  10. <link rel="stylesheet" media="screen" href="/static/css/admin.css">
  11. <link rel="icon" href="/static/img/logo.png" type="image/x-icon">
  12. <script src="/static/js/jquery.min.js"></script>
  13. <script src="/static/js/common.js"></script>
  14. <script src="/static/js/grey.js"></script>
  15. </head>
  16. <body>
  17. <script>
  18. $(document).ready(function () {
  19. function isPhone() {
  20. //获取浏览器navigator对象的userAgent属性(浏览器用于HTTP请求的用户代理头的值)
  21. var info = navigator.userAgent;
  22. var isMobile = /iPhone|iPad|iPod|Android|mobile/i.test(info) || window.screen.width < 768 || window.screen.height < 768;
  23. console.log('navigator.userAgent:',info,'isMobile:',isMobile);
  24. //通过正则表达式的test方法判断是否包含“Mobile”字符串
  25. //如果包含“Mobile”(是手机设备)则返回true
  26. return isMobile;
  27. }
  28. const IS_MOBILE = isPhone();
  29. console.log('IS_MOBILE:',IS_MOBILE);
  30. $(".view").click(function () {
  31. let rule = this.innerText.trim();
  32. // location.href = '/admin/view/' + rule + '.js';
  33. if(IS_MOBILE){
  34. location.href = '/admin/edit2/' + rule + '.js';
  35. }else{
  36. location.href = '/admin/edit/' + rule + '.js';
  37. }
  38. });
  39. $(".view_home").click(function () {
  40. let rule = this.getAttribute('value').trim();
  41. location.href = '/vod?{% if js0_password %}pwd={{js0_password}}&{% endif %}rule=' + rule;
  42. });
  43. $(".view_search").click(function () {
  44. let rule = this.getAttribute('value').trim();
  45. location.href = '/vod?{% if js0_password %}pwd={{js0_password}}&{% endif %}rule=' + rule + '&wd=斗罗大陆';
  46. });
  47. $("#checkUpdate").click(function () {
  48. console.log('开始检查升级...');
  49. $.get("/admin/get_ver", function (data, status) {
  50. console.log("数据: " + data + "\n状态: " + status);
  51. if (data.msg) {
  52. alert(data.msg);
  53. return false
  54. } else {
  55. if (data.local_ver && data.online_ver && !data.msg) {
  56. if (data.local_ver !== data.online_ver) {
  57. msg = `本地版本:${data.local_ver}\n线上版本:${data.online_ver}\n是否立即执行升级?`;
  58. if (confirm(msg)) {
  59. $.get("/admin/update_ver", function (data, status) {
  60. console.log(data);
  61. if (data.code === 200) {
  62. // alert(data.msg+'\n除主程序app.py需要自行检测替换升级外,其他关键文件全部更新完毕');
  63. alert(data.msg);
  64. location.reload();
  65. } else {
  66. alert(data.msg || '未知数据,具体到数据控制台查看');
  67. console.log('升级失败了...');
  68. return false
  69. }
  70. });
  71. }
  72. } else {
  73. alert('已经是最新版,无需升级!')
  74. }
  75. } else if (data.msg) {
  76. alert('检测升级疑似发生了问题:\n' + data.msg);
  77. } else {
  78. alert('已经是最新版,无需升级!')
  79. }
  80. }
  81. });
  82. });
  83. $(".clear").click(function () {
  84. let rule = this.getAttribute('value').trim();
  85. if (confirm('确认删除内置规则:' + rule + '?')) {
  86. let code = $.ajax({ url: '/admin/clear/' + rule + '.js', async: false }).responseText;
  87. code = typeof (code) === "object" ? code : JSON.parse(code);
  88. if (code.code === 200) {
  89. alert('操作成功!\n' + code.msg);
  90. location.reload()
  91. } else {
  92. alert('操作失败!\n' + code.msg);
  93. }
  94. }
  95. });
  96. $('#upload').click(function () {
  97. var file_data = $("input[name='file']").prop("files")[0];
  98. // console.log(file_data);
  99. if (!file_data) {
  100. alert('文件必选');
  101. return false
  102. }
  103. var name = file_data.name;
  104. if (!name.endsWith('.js')) {
  105. alert('仅支持上传js文件');
  106. return false
  107. }
  108. var form_data = new FormData();
  109. // 把所有表单信息
  110. form_data.append("id", "001");
  111. form_data.append("name", name);
  112. form_data.append("file", file_data);
  113. $.ajax({
  114. type: "POST",
  115. url: "/admin/upload",
  116. dataType: "json",
  117. processData: false, // 注意:让jQuery不要处理数据
  118. contentType: false, // 注意:让jQuery不要设置contentType
  119. data: form_data
  120. }).success(function (ret) {
  121. console.log(ret);
  122. if(ret.msg && ret.msg.includes('文件已存在')){
  123. if (confirm(ret.msg+'\n'+'是否覆盖写入?')) {
  124. console.log('覆盖写入');
  125. $.ajax({
  126. type: "POST",
  127. url: "/admin/upload?force=1",
  128. dataType: "json",
  129. processData: false, // 注意:让jQuery不要处理数据
  130. contentType: false, // 注意:让jQuery不要设置contentType
  131. data: form_data
  132. }).success((ret)=>{
  133. console.log(ret);
  134. alert(ret.msg);
  135. if(ret.msg && ret.msg.includes('文件上传成功')){
  136. location.reload();
  137. }
  138. }).fail((ret)=>{
  139. console.log(ret);
  140. alert(ret.msg);
  141. });
  142. }
  143. }else{
  144. alert(ret.msg);
  145. }
  146. if(ret.msg && ret.msg.includes('文件上传成功')){
  147. location.reload();
  148. }
  149. }).fail(function (ret) {
  150. console.log(ret);
  151. alert(ret.msg);
  152. });
  153. });
  154. $('#update_lives').click(function () {
  155. let live_url = $('#live_url').val();
  156. // console.log(live_url);
  157. let new_live_url = prompt('输入临时同步远程直播源地址(自动获取当前配置)', live_url);
  158. if (new_live_url.startsWith('http')) {
  159. $.get("/admin/update_lives?url=" + new_live_url, function (data, status) {
  160. console.log("数据: " + data + "\n状态: " + status);
  161. if (data.code === 200) {
  162. alert('操作成功!\n' + data.msg);
  163. // location.reload();
  164. } else {
  165. alert('操作失败!\n' + data.msg);
  166. }
  167. });
  168. }
  169. });
  170. $('#write_lives').click(function () {
  171. let live_url = $('#live_url').val();
  172. let new_live_url = prompt('请修改默认的远程直播源地址', live_url);
  173. if (new_live_url) {
  174. console.log('修改直播源地址为:' + new_live_url);
  175. $.get("/admin/write_live_url?url=" + new_live_url, function (data, status) {
  176. console.log("数据: " + data + "\n状态: " + status);
  177. if (data.code === 200) {
  178. alert('操作成功!\n' + data.msg);
  179. location.reload();
  180. } else {
  181. alert('操作失败!\n' + data.msg);
  182. }
  183. });
  184. }
  185. });
  186. $('#force_update').click(function () {
  187. let msg = `
  188. 升级过程中由于新版本升级脚本发生改变可能会导致升级完毕但是升级不完整。
  189. 此时需要重启服务后执行强制升级操作通过更新后的升级脚本把本地升级包文件再次覆盖完成完整升级。
  190. 是否继续(请确认你升级完后重启过,不然点确定毫无必要)?
  191. `;
  192. if (confirm(msg)) {
  193. $.get("/admin/force_update", function (data, status) {
  194. console.log(data);
  195. if (data.code === 200) {
  196. // alert(data.msg+'\n除主程序app.py需要自行检测替换升级外,其他关键文件全部更新完毕');
  197. alert(data.msg);
  198. location.reload();
  199. } else {
  200. alert(data.msg || '未知数据,具体到数据控制台查看');
  201. console.log('升级失败了...');
  202. return false
  203. }
  204. });
  205. }
  206. });
  207. $('#choose_update').click(function () {
  208. $('#fileInput').click();
  209. });
  210. $('#fileInput').change(function () {
  211. //获取选择的文件信息
  212. let file = this.files[0];
  213. //执行上传操作
  214. if(file){
  215. console.log(file);
  216. if(file.name.includes('dr_py')||file.name.includes('drpy')){
  217. if(confirm('已选择文件:'+file.name+',体积:'+(file.size/1024).toFixed(2)+'kb 进行手动升级,是否继续?')){
  218. var name = file.name;
  219. if (!name.endsWith('.zip')) {
  220. alert('仅支持上传zip文件');
  221. return false
  222. }
  223. let form_data = new FormData();
  224. // 把所有表单信息
  225. form_data.append("id", "001");
  226. form_data.append("name", name);
  227. form_data.append("file", file);
  228. $.ajax({
  229. type: "POST",
  230. url: "/admin/upload_update?force=1",
  231. dataType: "json",
  232. processData: false, // 注意:让jQuery不要处理数据
  233. contentType: false, // 注意:让jQuery不要设置contentType
  234. data: form_data
  235. }).success(function (ret) {
  236. console.log(ret);
  237. alert(ret.msg);
  238. if(ret.msg && ret.msg.includes('文件上传成功')){
  239. location.reload();
  240. }
  241. }).fail(function (ret) {
  242. console.log(ret);
  243. alert(ret.msg);
  244. });
  245. }
  246. }else{
  247. alert('你选择的文件:'+file.name+'看起来不像是drpy的升级文件压缩包。一般文件名长这样:dr_py-main.zip,请重新选择')
  248. }
  249. }
  250. });
  251. $('#use_py').click(function () {
  252. $.get("/admin/change_use_py", function (data, status) {
  253. console.log(data);
  254. if (data.code === 200) {
  255. alert(data.msg);
  256. location.reload();
  257. } else {
  258. alert(data.msg);
  259. console.log('升级失败了...');
  260. return false
  261. }
  262. });
  263. });
  264. $('#force_up').click(function () {
  265. $.get("/admin/change_force_up", function (data, status) {
  266. console.log(data);
  267. if (data.code === 200) {
  268. alert(data.msg);
  269. location.reload();
  270. } else {
  271. alert(data.msg);
  272. console.log('升级失败了...');
  273. return false
  274. }
  275. });
  276. });
  277. $("#logtail").click(function () {
  278. location.href = '/admin/logtail';
  279. });
  280. $('#clear_drop').click(function () {
  281. if(confirm('若js目录存在同名的jsd文件则视为该源为废弃源。执行此功能将清理与jsd文件同名的js文件。执行此功能前请确保项目的jsd文件跟仓库一致,防止误删。推荐进容器 rm -rf js/*.jsd 后强制升级一次再使用此功能,后续升级时会自动清空旧版jsd文件。立即执行则确认否则取消执行')){
  282. $.get("/admin/clear_drop", function (data, status) {
  283. console.log(data);
  284. if (data.code === 200) {
  285. alert(data.msg);
  286. location.reload();
  287. } else {
  288. alert(data.msg);
  289. console.log('清理失败了...');
  290. return false
  291. }
  292. });
  293. }
  294. });
  295. $('#lives').click(function () {
  296. location.href = '/admin/lives'
  297. });
  298. $('#lives_web').click(function () {
  299. open('/admin/lives_web');
  300. });
  301. $('#live_tools').click(function (){
  302. open('/admin/tools');
  303. })
  304. $("summary").click(function() {
  305. // console.log('summary被点击');
  306. const details = $('details');
  307. if(details.attr("open")){
  308. $(this).text('数据列表已隐藏 点击展开详情');
  309. }else{
  310. $(this).text('数据列表已展开 点击隐藏详情');
  311. }
  312. details.click();
  313. });
  314. });
  315. function getFileSize(fileObj) {
  316. $('#file_size').text('文件大小为:' + (fileObj.files[0].size / 1024).toFixed(2) + 'kb');
  317. }
  318. </script>
  319. <div class="title">欢迎使用DR-PY管理界面<div><span class="ver_title">当前版本: {{ ver }}</span><span
  320. class="ver_title">框架开发:道长</span><span class="ver_title">框架美化:蓝莓</span></div>
  321. </div>
  322. <a href="/web/player1?url=" class="btn-player" target="_blank">MUI播放器</a>
  323. <a href="/web/player2?url=" class="btn-player" target="_blank">P2P播放器</a>
  324. <a href="/web/player3?url=https://vip.ffzyread1.com/20230601/13234_55ed2d56/index.m3u8" class="btn-player" target="_blank">P2P播放器-GO</a>
  325. <a href="/web/player4?url=" class="btn-player" target="_blank">P2P播放器-hls</a>
  326. <div class="nav">
  327. <!-- 列表 -->
  328. <ul>
  329. <!-- 一级菜单 -->
  330. <li class="nav-litem">
  331. <a href="/index">返回首页</a>
  332. </li>
  333. <li class="nav-litem">
  334. <a href="javascript:;">功能管理</a>
  335. <!-- 二级菜单 -->
  336. <ul>
  337. <li><a href="/admin/settings">设置中心</a></li>
  338. <li><a href="/layui/index">未来功能</a></li>
  339. <li><a href="javascript:void(0);" class="funcbtn" id="logtail">在线日志</a></li>
  340. <li><a href="/vods" class="funcbtn" target="_blank">搜索看板</a></li>
  341. <li><a href="javascript:void(0);" class="funcbtn" id="clear_drop">废弃源清理</a></li>
  342. </ul>
  343. </li>
  344. <li class="nav-litem">
  345. <a href="javascript:;">项目升级</a>
  346. <!-- 二级菜单 -->
  347. <ul>
  348. <li><a href="javascript:void(0);" class="funcbtn" id="checkUpdate">检测升级</a></li>
  349. <li><a href="javascript:void(0);" class="funcbtn" id="force_update">强制升级</a></li>
  350. <li><a href="javascript:void(0);" class="funcbtn" id="choose_update">手动升级</a></li>
  351. <li><a href="javascript:void(0);" class="funcbtn" id="force_up">已{% if force_up=='1' %}启用{% else %}关闭{% endif %}强制下载</a></li>
  352. <input type="file" id="fileInput" accept=".zip,.rar" style="display:none;">
  353. </ul>
  354. </li>
  355. <li class="nav-litem">
  356. <a href="javascript:;">直播设置</a>
  357. <!-- 二级菜单 -->
  358. <ul>
  359. <li><a href="javascript:void(0);" class="funcbtn" id="write_lives">修改直播源</a></li>
  360. <li><a href="javascript:void(0);" class="funcbtn" id="update_lives">同步直播源</a></li>
  361. <li><a href="javascript:void(0);" class="funcbtn" id="use_py">已{% if pystate=='1' %}启用{% else %}关闭{% endif %}py源</a></li>
  362. <li><a href="javascript:void(0);" class="funcbtn" id="lives">直播源列表</a></li>
  363. <li><a href="javascript:void(0);" class="funcbtn" id="lives_web">网页在线直播</a></li>
  364. <li><a href="javascript:void(0);" class="funcbtn" id="live_tools">转换工具</a></li>
  365. </ul>
  366. </li>
  367. </ul>
  368. </div>
  369. <input id="live_url" value="{{live_url}}" style="display: none">
  370. <p class="box">你可以在此界面在线管理JS目录里规则文件的上传/删除</p>
  371. <form action="/admin/upload" method="POST" enctype="multipart/form-data">
  372. <!-- <input type = "file" name = "file" class="btn" accept=".js" onchange="getFileSize(this)"/>-->
  373. <input type="file" name="file" class="btn" onchange="getFileSize(this)" accept=".js,.jsd,.txt"/>
  374. <!-- <input type = "submit" value="上传" class="btn"/>-->
  375. <input type="button" id="upload" value="上传" class="btn" />
  376. </form>
  377. <p id="file_size"></p>
  378. <details open>
  379. <summary class="xl">数据列表已展开 点击隐藏详情</summary>
  380. <h4>规则列表数据-共{{rules.count+cache_count}}条(内置:{{rules.count}} 缓存:{{cache_count}})</h4>
  381. {% if rules.count < 1 %} <h3>暂无内置的规则</h3>
  382. {% endif %}
  383. <div class="zt">
  384. {% for rule in rules.list %}
  385. <div class="red">
  386. <div class="mz"><a class="view" href="javascript:void(0);">{{ rule.name }}</a></div>
  387. <div class="sa"><a class="preview_home" href="/web/{{ rule.name }}/mxpro" value="{{ rule.name }}" target="_blank">🌐</a></div>
  388. <div class="sj"><a class="view_home" href="javascript:void(0);" value="{{ rule.name }}">🏠</a></div>
  389. <div class="ss"><a class="view_search" href="javascript:void(0);" value="{{ rule.name }}">🔍️</a></div>
  390. <div class="sc"><a class="clear" href="javascript:void(0);" value="{{ rule.name }}">🗑</a></div>
  391. </div>
  392. {% endfor %}
  393. </div>
  394. </details>
  395. </body>
  396. </html>