InPanel 1.2.6__tar.gz → 1.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/PKG-INFO +1 -1
  2. {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/SOURCES.txt +29 -3
  3. {inpanel-1.2.6 → inpanel-1.2.7}/PKG-INFO +1 -1
  4. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/app.py +2 -1
  5. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/base.py +14 -8
  6. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/config.py +1 -1
  7. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/filelock.py +1 -1
  8. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/pxssh.py +2 -2
  9. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/acme.py +16 -18
  10. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/aliyuncs.py +3 -4
  11. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/apt.py +35 -35
  12. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/brew.py +46 -46
  13. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/certificate.py +7 -7
  14. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/config.py +3 -3
  15. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/cron.py +7 -7
  16. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/disk.py +19 -22
  17. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/dnf.py +25 -25
  18. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/docker_source.py +30 -30
  19. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/file.py +443 -154
  20. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/ftp.py +19 -19
  21. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/httpd.py +10 -10
  22. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/login.py +7 -8
  23. inpanel-1.2.7/inpanel/mod/logs.py +840 -0
  24. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/mysql.py +68 -69
  25. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/nginx.py +2326 -2326
  26. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/php.py +7 -7
  27. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/pip.py +13 -13
  28. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/process.py +3 -3
  29. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/query.py +4 -4
  30. inpanel-1.2.7/inpanel/mod/redis.py +518 -0
  31. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/remote.py +10 -10
  32. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/server.py +92 -97
  33. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/service.py +1 -1
  34. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/setting.py +3 -3
  35. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/ssh.py +324 -324
  36. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/task.py +2 -1
  37. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/user.py +5 -5
  38. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/yum.py +50 -50
  39. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/css/global.css +5 -14
  40. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/index.html +6 -2
  41. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/controllers.js +0 -9
  42. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/database.js +258 -12
  43. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/file.js +139 -42
  44. inpanel-1.2.7/inpanel/public/js/controllers/logs.js +291 -0
  45. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/utils.js +182 -23
  46. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/core.js +247 -246
  47. inpanel-1.2.7/inpanel/public/lib/codemirror/addon/edit/matchbrackets.min.js +1 -0
  48. inpanel-1.2.7/inpanel/public/lib/codemirror/addon/search/match-highlighter.min.js +1 -0
  49. inpanel-1.2.7/inpanel/public/lib/codemirror/addon/selection/active-line.min.js +1 -0
  50. inpanel-1.2.7/inpanel/public/lib/codemirror/codemirror.min.css +1 -0
  51. inpanel-1.2.7/inpanel/public/lib/codemirror/codemirror.min.js +1 -0
  52. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/css/css.min.js +1 -0
  53. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/diff/diff.min.js +1 -0
  54. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/dockerfile/dockerfile.min.js +1 -0
  55. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/go/go.min.js +1 -0
  56. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/htmlmixed/htmlmixed.min.js +1 -0
  57. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/javascript/javascript.min.js +1 -0
  58. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/lua/lua.min.js +1 -0
  59. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/markdown/markdown.min.js +1 -0
  60. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/nginx/nginx.min.js +1 -0
  61. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/perl/perl.min.js +1 -0
  62. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/php/php.min.js +1 -0
  63. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/properties/properties.min.js +1 -0
  64. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/python/python.min.js +1 -0
  65. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/ruby/ruby.min.js +1 -0
  66. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/rust/rust.min.js +1 -0
  67. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/shell/shell.min.js +1 -0
  68. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/sql/sql.min.js +1 -0
  69. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/toml/toml.min.js +1 -0
  70. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/xml/xml.min.js +1 -0
  71. inpanel-1.2.7/inpanel/public/lib/codemirror/mode/yaml/yaml.min.js +1 -0
  72. inpanel-1.2.7/inpanel/public/partials/database/index.html +401 -0
  73. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/file/trash.html +4 -2
  74. inpanel-1.2.7/inpanel/public/partials/logs.html +442 -0
  75. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/index.html +20 -20
  76. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/sources.html +181 -126
  77. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/templates/index.html +6 -2
  78. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/utils.py +9 -10
  79. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/web.py +65 -40
  80. {inpanel-1.2.6 → inpanel-1.2.7}/pyproject.toml +1 -1
  81. inpanel-1.2.6/inpanel/public/lib/codemirror/codemirror-compressed.js +0 -1
  82. inpanel-1.2.6/inpanel/public/lib/codemirror/codemirror.css +0 -173
  83. inpanel-1.2.6/inpanel/public/partials/database/index.html +0 -172
  84. inpanel-1.2.6/inpanel/public/partials/log.html +0 -83
  85. {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/dependency_links.txt +0 -0
  86. {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/entry_points.txt +0 -0
  87. {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/requires.txt +0 -0
  88. {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/top_level.txt +0 -0
  89. {inpanel-1.2.6 → inpanel-1.2.7}/LICENSE +0 -0
  90. {inpanel-1.2.6 → inpanel-1.2.7}/MANIFEST.in +0 -0
  91. {inpanel-1.2.6 → inpanel-1.2.7}/README.md +0 -0
  92. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/__init__.py +0 -0
  93. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/__init__.py +0 -0
  94. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/async_process.py +0 -0
  95. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/magic.py +0 -0
  96. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/pyDes.py +0 -0
  97. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/__init__.py +0 -0
  98. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/docker.py +0 -0
  99. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall.py +0 -0
  100. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_base.py +0 -0
  101. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_firewalld.py +0 -0
  102. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_iptables.py +0 -0
  103. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_macos.py +0 -0
  104. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_ufw.py +0 -0
  105. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/lighttpd.py +0 -0
  106. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/named.py +0 -0
  107. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package.py +0 -0
  108. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_apt.py +0 -0
  109. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_base.py +0 -0
  110. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_brew.py +0 -0
  111. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_dnf.py +0 -0
  112. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_map.py +0 -0
  113. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_yum.py +0 -0
  114. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/plugins.py +0 -0
  115. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/proftpd.py +0 -0
  116. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/pureftpd.py +0 -0
  117. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/service_manager.py +0 -0
  118. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/shell.py +0 -0
  119. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/system.py +0 -0
  120. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/vsftpd.py +0 -0
  121. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/plugin.py +0 -0
  122. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/favicon.ico +0 -0
  123. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/images/alipay.jpg +0 -0
  124. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/images/loading.gif +0 -0
  125. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/images/weixin.jpg +0 -0
  126. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/container.js +0 -0
  127. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/ecs.js +0 -0
  128. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/plugins.js +0 -0
  129. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/service.js +0 -0
  130. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/site.js +0 -0
  131. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/directives.js +0 -0
  132. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/filters.js +0 -0
  133. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/services.js +0 -0
  134. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/angular/1.0.2/angular-resource.min.js +0 -0
  135. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/angular/1.0.2/angular.min.js +0 -0
  136. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/angular/1.0.8/angular.min.js +0 -0
  137. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.css +0 -0
  138. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.css.map +0 -0
  139. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css +0 -0
  140. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css.map +0 -0
  141. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.css +0 -0
  142. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.css.map +0 -0
  143. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.min.css +0 -0
  144. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.min.css.map +0 -0
  145. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  146. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.svg +0 -0
  147. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  148. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  149. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
  150. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
  151. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/img/glyphicons-halflings.png +0 -0
  152. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/js/bootstrap.js +0 -0
  153. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/js/bootstrap.min.js +0 -0
  154. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/js/npm.js +0 -0
  155. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/jquery/jquery-1.12.4.min.js +0 -0
  156. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/md5/md5.js +0 -0
  157. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/md5/md5.min.js +0 -0
  158. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/message.html +0 -0
  159. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/navbar.html +0 -0
  160. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/selector.html +0 -0
  161. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvbase.html +0 -0
  162. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvext.html +0 -0
  163. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvfile.html +0 -0
  164. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvinstall.html +0 -0
  165. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvlog.html +0 -0
  166. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvminiop.html +0 -0
  167. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvuninstall.html +0 -0
  168. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvupdate.html +0 -0
  169. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/index.html +0 -0
  170. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/dbedit.html +0 -0
  171. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/dbnew.html +0 -0
  172. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/useredit.html +0 -0
  173. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/usernew.html +0 -0
  174. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/account.html +0 -0
  175. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/ecs.html +0 -0
  176. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/index.html +0 -0
  177. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/setings.html +0 -0
  178. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/file/file.html +0 -0
  179. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ftp.html +0 -0
  180. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/login.html +0 -0
  181. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/logout.html +0 -0
  182. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/main.html +0 -0
  183. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/config.html +0 -0
  184. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/detail.html +0 -0
  185. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/index.html +0 -0
  186. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/info.html +0 -0
  187. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/secure.html +0 -0
  188. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/apache.html +0 -0
  189. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/cron.html +0 -0
  190. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/fail2ban.html +0 -0
  191. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/firewalld.html +0 -0
  192. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/index.html +0 -0
  193. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/iptables.html +0 -0
  194. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java11.html +0 -0
  195. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java17.html +0 -0
  196. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java21.html +0 -0
  197. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java8.html +0 -0
  198. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/lighttpd.html +0 -0
  199. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/mariadb.html +0 -0
  200. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/memcache.html +0 -0
  201. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/minio.html +0 -0
  202. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/mongodb.html +0 -0
  203. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/mysql.html +0 -0
  204. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/named.html +0 -0
  205. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nginx.html +0 -0
  206. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs18.html +0 -0
  207. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs20.html +0 -0
  208. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs22.html +0 -0
  209. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs24.html +0 -0
  210. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/ntp.html +0 -0
  211. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php.html +0 -0
  212. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php56.html +0 -0
  213. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php74.html +0 -0
  214. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php80.html +0 -0
  215. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php81.html +0 -0
  216. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php82.html +0 -0
  217. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php83.html +0 -0
  218. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php84.html +0 -0
  219. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/proftpd.html +0 -0
  220. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/pureftpd.html +0 -0
  221. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/redis.html +0 -0
  222. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/samba.html +0 -0
  223. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/sendmail.html +0 -0
  224. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/ssh.html +0 -0
  225. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/tomcat.html +0 -0
  226. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/ufw.html +0 -0
  227. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/vsftpd.html +0 -0
  228. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/setting.html +0 -0
  229. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/site/apache/site.html +0 -0
  230. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/site/index.html +0 -0
  231. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/site/nginx/site.html +0 -0
  232. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/sorry.html +0 -0
  233. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/autofm.html +0 -0
  234. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/backup.html +0 -0
  235. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/index.html +0 -0
  236. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/migrate.html +0 -0
  237. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/movedata.html +0 -0
  238. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/remote.html +0 -0
  239. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/cron.html +0 -0
  240. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/firewall.html +0 -0
  241. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/network.html +0 -0
  242. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/process.html +0 -0
  243. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/shell.html +0 -0
  244. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/ssl.html +0 -0
  245. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/task.html +0 -0
  246. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/time.html +0 -0
  247. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/user.html +0 -0
  248. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/robots.txt +0 -0
  249. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/templates/file/preview.html +0 -0
  250. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/__init__.py +0 -0
  251. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/__init__.py +0 -0
  252. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/_common.json +0 -0
  253. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/categories.json +0 -0
  254. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/database.json +0 -0
  255. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/ftp.json +0 -0
  256. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/http.json +0 -0
  257. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/java.json +0 -0
  258. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/mail.json +0 -0
  259. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/nodejs.json +0 -0
  260. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/php.json +0 -0
  261. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/security.json +0 -0
  262. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/storage.json +0 -0
  263. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/system.json +0 -0
  264. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/__init__.py +0 -0
  265. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/apt.json +0 -0
  266. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/brew.json +0 -0
  267. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/dnf.json +0 -0
  268. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/docker.json +0 -0
  269. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/package_map.json +0 -0
  270. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/pip.json +0 -0
  271. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/third_party.json +0 -0
  272. {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/yum.json +0 -0
  273. {inpanel-1.2.6 → inpanel-1.2.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: InPanel
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: InPanel - A Server Management Tool
5
5
  Author-email: Jackson Dou <jksdou@qq.com>
6
6
  Maintainer-email: Jackson Dou <jksdou@qq.com>
@@ -44,6 +44,7 @@ inpanel/mod/ftp.py
44
44
  inpanel/mod/httpd.py
45
45
  inpanel/mod/lighttpd.py
46
46
  inpanel/mod/login.py
47
+ inpanel/mod/logs.py
47
48
  inpanel/mod/mysql.py
48
49
  inpanel/mod/named.py
49
50
  inpanel/mod/nginx.py
@@ -61,6 +62,7 @@ inpanel/mod/process.py
61
62
  inpanel/mod/proftpd.py
62
63
  inpanel/mod/pureftpd.py
63
64
  inpanel/mod/query.py
65
+ inpanel/mod/redis.py
64
66
  inpanel/mod/remote.py
65
67
  inpanel/mod/server.py
66
68
  inpanel/mod/service.py
@@ -89,6 +91,7 @@ inpanel/public/js/controllers/controllers.js
89
91
  inpanel/public/js/controllers/database.js
90
92
  inpanel/public/js/controllers/ecs.js
91
93
  inpanel/public/js/controllers/file.js
94
+ inpanel/public/js/controllers/logs.js
92
95
  inpanel/public/js/controllers/plugins.js
93
96
  inpanel/public/js/controllers/service.js
94
97
  inpanel/public/js/controllers/site.js
@@ -114,15 +117,38 @@ inpanel/public/lib/bootstrap/img/glyphicons-halflings.png
114
117
  inpanel/public/lib/bootstrap/js/bootstrap.js
115
118
  inpanel/public/lib/bootstrap/js/bootstrap.min.js
116
119
  inpanel/public/lib/bootstrap/js/npm.js
117
- inpanel/public/lib/codemirror/codemirror-compressed.js
118
- inpanel/public/lib/codemirror/codemirror.css
120
+ inpanel/public/lib/codemirror/codemirror.min.css
121
+ inpanel/public/lib/codemirror/codemirror.min.js
122
+ inpanel/public/lib/codemirror/addon/edit/matchbrackets.min.js
123
+ inpanel/public/lib/codemirror/addon/search/match-highlighter.min.js
124
+ inpanel/public/lib/codemirror/addon/selection/active-line.min.js
125
+ inpanel/public/lib/codemirror/mode/css/css.min.js
126
+ inpanel/public/lib/codemirror/mode/diff/diff.min.js
127
+ inpanel/public/lib/codemirror/mode/dockerfile/dockerfile.min.js
128
+ inpanel/public/lib/codemirror/mode/go/go.min.js
129
+ inpanel/public/lib/codemirror/mode/htmlmixed/htmlmixed.min.js
130
+ inpanel/public/lib/codemirror/mode/javascript/javascript.min.js
131
+ inpanel/public/lib/codemirror/mode/lua/lua.min.js
132
+ inpanel/public/lib/codemirror/mode/markdown/markdown.min.js
133
+ inpanel/public/lib/codemirror/mode/nginx/nginx.min.js
134
+ inpanel/public/lib/codemirror/mode/perl/perl.min.js
135
+ inpanel/public/lib/codemirror/mode/php/php.min.js
136
+ inpanel/public/lib/codemirror/mode/properties/properties.min.js
137
+ inpanel/public/lib/codemirror/mode/python/python.min.js
138
+ inpanel/public/lib/codemirror/mode/ruby/ruby.min.js
139
+ inpanel/public/lib/codemirror/mode/rust/rust.min.js
140
+ inpanel/public/lib/codemirror/mode/shell/shell.min.js
141
+ inpanel/public/lib/codemirror/mode/sql/sql.min.js
142
+ inpanel/public/lib/codemirror/mode/toml/toml.min.js
143
+ inpanel/public/lib/codemirror/mode/xml/xml.min.js
144
+ inpanel/public/lib/codemirror/mode/yaml/yaml.min.js
119
145
  inpanel/public/lib/jquery/jquery-1.12.4.min.js
120
146
  inpanel/public/lib/md5/md5.js
121
147
  inpanel/public/lib/md5/md5.min.js
122
148
  inpanel/public/partials/ftp.html
123
- inpanel/public/partials/log.html
124
149
  inpanel/public/partials/login.html
125
150
  inpanel/public/partials/logout.html
151
+ inpanel/public/partials/logs.html
126
152
  inpanel/public/partials/main.html
127
153
  inpanel/public/partials/secure.html
128
154
  inpanel/public/partials/setting.html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: InPanel
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: InPanel - A Server Management Tool
5
5
  Author-email: Jackson Dou <jksdou@qq.com>
6
6
  Maintainer-email: Jackson Dou <jksdou@qq.com>
@@ -125,7 +125,7 @@ def cmd_start():
125
125
  force_https = config.getboolean('server', 'forcehttps')
126
126
  print(f'InPanel: running on: http{"s" if force_https else ""}://*:{server_port}')
127
127
  else:
128
- print('InPanel: failed to start, check log file: %s' % logfile)
128
+ print(f'InPanel: failed to start, check log file: {logfile}')
129
129
  sys.exit(1)
130
130
  return
131
131
  except OSError as e:
@@ -384,6 +384,7 @@ def run_server():
384
384
  (r'/api/service/(.+?)(?:/(.+))?', web.ServiceHandler),
385
385
  (r'/api/firewall/(.+)', web.FirewallHandler),
386
386
  (r'/api/setting/(.+)', web.SettingHandler),
387
+ (r'/api/logs/(.+)', web.LogsHandler),
387
388
  (r'/api/operation/(.+)', web.OperationHandler),
388
389
  (r'/api/task/(.+)', web.TaskHandler),
389
390
  (r'/api/sitepackage/(.+)', web.SitePackageHandler),
@@ -40,8 +40,8 @@ __author__ = 'Jackson Dou'
40
40
  __license__ = 'BSD'
41
41
 
42
42
  app_name = 'InPanel'
43
- releasetime = '2026-07-22'
44
- DEBUG = True
43
+ releasetime = '2026-07-26'
44
+ DEBUG = False
45
45
  COMMENTFLAG = '#INPANEL#'
46
46
  GENBY = 'AUTOMATICALLY GENERATED BY INPANEL'
47
47
 
@@ -62,14 +62,15 @@ app_api = {
62
62
  }
63
63
 
64
64
  execfile = '/usr/bin/inpanel'
65
- data_path = '/var/lib/inpanel/'
66
65
  config_path = '/etc/inpanel/'
66
+ data_path = '/var/lib/inpanel/'
67
+ logging_path = '/var/log/inpanel/'
67
68
  config_file = '/etc/inpanel/config.ini'
68
69
  lastfile_path = '/etc/inpanel/lastfile.ini'
69
70
  bookmarks_path = '/etc/inpanel/bookmarks.ini'
70
71
  upgrade_path = '/etc/inpanel/upgrade.ini'
71
- history_path = '/etc/inpanel/history.txt'
72
- logging_path = '/var/log/inpanel/'
72
+ files_log = '/var/log/inpanel/files.log'
73
+ filespath_log = '/var/log/inpanel/filespath.log'
73
74
  logfile = '/var/log/inpanel/main.log'
74
75
  logerror = '/var/log/inpanel/error.log'
75
76
  pidfile = '/var/run/inpanel.pid'
@@ -83,7 +84,11 @@ if hasattr(sys, 'frozen') and hasattr(sys, '_MEIPASS'):
83
84
  root_path = sys._MEIPASS
84
85
  else:
85
86
  package_dir = Path(__file__).parent.resolve()
87
+ is_develop_mode = False
86
88
  if package_dir.parts[-2] == 'site-packages' or 'dist-packages' in str(package_dir):
89
+ if Path(__file__).is_symlink():
90
+ is_develop_mode = True
91
+ if not is_develop_mode and (package_dir.parts[-2] == 'site-packages' or 'dist-packages' in str(package_dir)):
87
92
  run_type = 'system'
88
93
  root_path = str(package_dir)
89
94
  pkg_str = str(package_dir)
@@ -101,12 +106,13 @@ else:
101
106
  execfile = str(Path(root_path) / 'app.py')
102
107
  data_path = str(Path(root_path) / 'data')
103
108
  config_path = str(Path(root_path) / 'data')
109
+ logging_path = str(Path(root_path) / 'data')
104
110
  config_file = str(Path(root_path) / 'data' / 'config.ini')
105
111
  lastfile_path = str(Path(root_path) / 'data' / 'lastfile.ini')
106
112
  bookmarks_path = str(Path(root_path) / 'data' / 'bookmarks.ini')
107
113
  upgrade_path = str(Path(root_path) / 'data' / 'upgrade.ini')
108
- history_path = str(Path(root_path) / 'data' / 'history.txt')
109
- logging_path = str(Path(root_path) / 'data')
114
+ files_log = str(Path(root_path) / 'data' / 'files.log')
115
+ filespath_log = str(Path(root_path) / 'data' / 'filespath.log')
110
116
  logfile = str(Path(root_path) / 'data' / 'main.log')
111
117
  logerror = str(Path(root_path) / 'data' / 'error.log')
112
118
  pidfile = str(Path(root_path) / 'data' / 'inpanel.pid')
@@ -199,7 +205,7 @@ __all__ = [
199
205
  'releasetime', 'version_info', 'server_info', 'os_name', 'os_title',
200
206
  'os_version', 'os_versint', 'os_platform', 'kernel_name', 'kernel_release',
201
207
  'kernel_version', 'hostname', 'machine', 'lastfile_path', 'bookmarks_path', 'upgrade_path',
202
- 'history_path', 'logfile', 'logerror', 'pidfile', 'processor'
208
+ 'files_log', 'filespath_log', 'logfile', 'logerror', 'pidfile', 'processor'
203
209
  ]
204
210
 
205
211
  if __name__ == '__main__':
@@ -119,7 +119,7 @@ Examples:
119
119
  key = md5(randstr().encode('utf-8')).hexdigest()
120
120
  md5_password = md5(value.encode('utf-8')).hexdigest()
121
121
  pwd = hmac_new(key.encode('utf-8'), md5_password.encode('utf-8'), md5).hexdigest()
122
- value = '%s:%s' % (pwd, key)
122
+ value = f'{pwd}:{key}'
123
123
  logger.info(f'Password hash generated, key length: {len(key)}, hash length: {len(pwd)}')
124
124
 
125
125
  result = config.set(section, option, value)
@@ -21,7 +21,7 @@ class FileLock(object):
21
21
  the maximum timeout and the delay between each attempt to lock.
22
22
  """
23
23
  self.is_locked = False
24
- self.lockfile = str(Path.cwd() / ("%s.lock" % file_name))
24
+ self.lockfile = str(Path.cwd() / (f"{file_name}.lock"))
25
25
  self.file_name = file_name
26
26
  self.timeout = timeout
27
27
  self.delay = delay
@@ -186,8 +186,8 @@ class pxssh (spawn):
186
186
  if self.force_password:
187
187
  ssh_options = ssh_options + ' ' + self.SSH_OPTS
188
188
  if port is not None:
189
- ssh_options = ssh_options + ' -p %s'%(str(port))
190
- cmd = "ssh %s -l %s %s" % (ssh_options, username, server)
189
+ ssh_options = ssh_options + f' -p {port!s}'
190
+ cmd = f"ssh {ssh_options} -l {username} {server}"
191
191
 
192
192
  # This does not distinguish between a remote server 'password' prompt
193
193
  # and a local ssh 'passphrase' prompt (for unlocking a private key).
@@ -57,7 +57,7 @@ class ACME():
57
57
  proc = Popen(cmd_list, stdin=stdin, stdout=PIPE, stderr=PIPE)
58
58
  out, err = proc.communicate(cmd_input)
59
59
  if proc.returncode != 0:
60
- raise IOError("{0}\n{1}".format(err_msg, err))
60
+ raise IOError(f"{err_msg}\n{err}")
61
61
  return out
62
62
 
63
63
  def _b64(self, b):
@@ -85,8 +85,7 @@ class ACME():
85
85
  if depth < 100 and code == 400 and res_data['type'] == 'urn:ietf:params:acme:error:badNonce':
86
86
  raise IndexError(res_data) # 允许对无效 nonce 重试 100 次
87
87
  if code not in [200, 201, 204]:
88
- raise ValueError("{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format(
89
- err_msg, url, data, code, res_data))
88
+ raise ValueError(f"{err_msg}:\nUrl: {url}\nData: {data}\nResponse Code: {code}\nResponse: {res_data}")
90
89
  return res_data, code, headers
91
90
 
92
91
  def _s_request(self, url, payload, err_msg, depth=0):
@@ -96,7 +95,7 @@ class ACME():
96
95
  protected = {'url': url, 'alg': self.alg, "nonce": new_nonce}
97
96
  protected.update({"jwk": self.jwk} if self.acct_headers is None else {"kid": self.acct_headers['Location']})
98
97
  protected64 = self._b64(dumps(protected).encode('utf8'))
99
- protected_input = "{0}.{1}".format(protected64, payload64).encode('utf8')
98
+ protected_input = f"{protected64}.{payload64}".encode('utf8')
100
99
  cmd = ['openssl', 'dgst', '-sha256', '-sign', self.account_key]
101
100
  out = self._cmd(cmd, stdin=PIPE, cmd_input=protected_input, err_msg='OpenSSL Error')
102
101
  data = dumps({
@@ -146,8 +145,8 @@ class ACME():
146
145
  out = self._cmd(cmd, err_msg='openssl error')
147
146
  pub_pattern = r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)"
148
147
  pub_hex, pub_exp = re.search(pub_pattern, out.decode('utf8'), re.MULTILINE | re.DOTALL).groups()
149
- pub_exp = "{0:x}".format(int(pub_exp))
150
- pub_exp = "0{0}".format(pub_exp) if len(pub_exp) % 2 else pub_exp
148
+ pub_exp = f"{int(pub_exp):x}"
149
+ pub_exp = f"0{pub_exp}" if len(pub_exp) % 2 else pub_exp
151
150
  self.jwk = {
152
151
  'e': self._b64(unhexlify(pub_exp.encode('utf-8'))),
153
152
  'kty': 'RSA',
@@ -182,7 +181,7 @@ class ACME():
182
181
  # 查找域名
183
182
  print('Domains CSR parsing...')
184
183
  cmd = ['openssl', 'req', '-in', self.csr, '-noout', '-text']
185
- out = self._cmd(cmd, err_msg="Error loading {0}".format(self.csr))
184
+ out = self._cmd(cmd, err_msg=f"Error loading {self.csr}")
186
185
  domains = set([])
187
186
  common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", out.decode('utf8'))
188
187
  if common_name is not None:
@@ -193,7 +192,7 @@ class ACME():
193
192
  for san in subject_alt_names.group(1).split(", "):
194
193
  if san.startswith("DNS:"):
195
194
  domains.add(san[4:])
196
- print("Found domains: {0}".format(", ".join(domains)))
195
+ print(f"Found domains: {', '.join(domains)}")
197
196
  # print('domains', domains)
198
197
  if order == True:
199
198
  self.create_new_order(domains)
@@ -213,32 +212,31 @@ class ACME():
213
212
  for auth_url in order['authorizations']:
214
213
  authorization, _, _ = self._request(auth_url, err_msg='Error getting challenges')
215
214
  domain = authorization['identifier']['value']
216
- print("Domain {0} Verifying...".format(domain))
215
+ print(f"Domain {domain} Verifying...")
217
216
 
218
217
  # 找到 http-01 挑战并写入挑战文件
219
218
  challenge = [c for c in authorization['challenges'] if c['type'] == "http-01"][0]
220
219
  token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
221
- key_auth = "{0}.{1}".format(token, self.thumbprint)
220
+ key_auth = f"{token}.{self.thumbprint}"
222
221
  wellknown_path = str(Path(self.acme_check_dir) / token)
223
222
  with open(wellknown_path, 'w', encoding='utf-8') as f:
224
223
  f.write(key_auth)
225
224
 
226
225
  # 检查 wellknown 文件是否在指定位置
227
226
  try:
228
- wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(domain, token)
227
+ wellknown_url = f"http://{domain}/.well-known/acme-challenge/{token}"
229
228
  assert(disable_check or self._request(wellknown_url)[0] == key_auth)
230
229
  except (AssertionError, ValueError) as e:
231
230
  Path(wellknown_path).unlink()
232
- raise ValueError("Wrote file to {0}, but couldn't download {1}: {2}".format(
233
- wellknown_path, wellknown_url, e))
231
+ raise ValueError(f"Wrote file to {wellknown_path}, but couldn't download {wellknown_url}: {e}")
234
232
 
235
233
  # 告知挑战已完成
236
234
  self._s_request(
237
- challenge['url'], {}, "Error submitting challenges: {0}".format(domain))
238
- authorization = self._poll_until_not(auth_url, ["pending"], "Error checking challenge status for {0}".format(domain))
235
+ challenge['url'], {}, f"Error submitting challenges: {domain}")
236
+ authorization = self._poll_until_not(auth_url, ["pending"], f"Error checking challenge status for {domain}")
239
237
  if authorization['status'] != "valid":
240
- raise ValueError("Challenge did not pass for {0}: {1}".format(domain, authorization))
241
- print("Domain {0} verified!".format(domain))
238
+ raise ValueError(f"Challenge did not pass for {domain}: {authorization}")
239
+ print(f"Domain {domain} verified!")
242
240
 
243
241
  # 使用 CSR 完成订单
244
242
  print('Certificate signing...')
@@ -247,7 +245,7 @@ class ACME():
247
245
  # 轮询订单以监控其完成状态
248
246
  order = self._poll_until_not(order_headers['Location'], ['pending', 'processing'], 'Error checking order status')
249
247
  if order['status'] != 'valid':
250
- raise ValueError("Order failed: {0}".format(order))
248
+ raise ValueError(f"Order failed: {order}")
251
249
  self.certificate = order['certificate']
252
250
 
253
251
  def get_certificate(self, certificate=None):
@@ -32,8 +32,7 @@ class ECS(object):
32
32
  def _sign(self, params):
33
33
  paramstrings = []
34
34
  for k, v in sorted(params.items()):
35
- paramstrings.append('%s=%s' %
36
- (ECS._urlencode(k), ECS._urlencode(v)))
35
+ paramstrings.append(f'{ECS._urlencode(k)}={ECS._urlencode(v)}')
37
36
  datastrings = [
38
37
  ECS._urlencode('GET'),
39
38
  ECS._urlencode('/'),
@@ -240,7 +239,7 @@ if __name__ == '__main__':
240
239
  print()
241
240
 
242
241
  for region in regions['Regions']:
243
- print('## Zones in %s\n' % region['RegionCode'])
242
+ print(f"## Zones in {region['RegionCode']}\n")
244
243
  zones = ecs.DescribeZones(region['RegionCode'])
245
244
  if not zones[0]:
246
245
  pp.pprint(zones)
@@ -250,7 +249,7 @@ if __name__ == '__main__':
250
249
  print()
251
250
 
252
251
  for zone in zones['Zones']:
253
- print('## Instances in %s\n' % zone['ZoneCode'])
252
+ print(f"## Instances in {zone['ZoneCode']}\n")
254
253
  instances = ecs.DescribeInstanceStatus(
255
254
  region['RegionCode'], zone['ZoneCode'])[1]
256
255
  pp.pprint(instances)
@@ -8,7 +8,7 @@
8
8
  '''APT 软件源管理模块
9
9
 
10
10
  概念说明:
11
- - 镜像源(mirror):基础发行版仓库的 URL 地址,切换本质是修改已有 .list 文件中 deb URL 的域名。
11
+ - 镜像站(mirror):基础发行版仓库的 URL 地址,切换本质是修改已有 .list 文件中 deb URL 的域名。
12
12
  - 软件仓库(repo):完整的 .list 配置文件,可以添加自定义仓库来安装特定软件(如 PHP SURY、NodeSource)。
13
13
  '''
14
14
 
@@ -102,13 +102,13 @@ def _extract_domain(url):
102
102
  """从 URL 中提取域名(scheme://host)"""
103
103
  try:
104
104
  p = urlparse(url)
105
- return '%s://%s' % (p.scheme, p.netloc)
105
+ return f'{p.scheme}://{p.netloc}'
106
106
  except Exception:
107
107
  return url
108
108
 
109
109
 
110
110
  def get_mirrors():
111
- """获取镜像源列表"""
111
+ """获取镜像站列表"""
112
112
  sources = _load_sources_config()
113
113
  active_url = _get_active_url()
114
114
  active_domain = _extract_domain(active_url) if active_url else ''
@@ -376,7 +376,7 @@ def refresh_cache():
376
376
  status, output = getstatusoutput('apt update 2>&1')
377
377
  if status == 0:
378
378
  return {'code': 0, 'msg': 'apt 索引已更新!'}
379
- return {'code': -1, 'msg': 'apt 索引更新失败:%s' % output}
379
+ return {'code': -1, 'msg': f'apt 索引更新失败:{output}'}
380
380
 
381
381
 
382
382
  def get_repo_list():
@@ -436,10 +436,10 @@ def install_package(name):
436
436
  return {'code': -1, 'msg': '软件名称不能为空!'}
437
437
  if not is_installed():
438
438
  return {'code': -1, 'msg': 'apt 未安装!'}
439
- status, output = getstatusoutput('apt install -y %s 2>&1' % name)
439
+ status, output = getstatusoutput(f'apt install -y {name} 2>&1')
440
440
  if status == 0:
441
- return {'code': 0, 'msg': '软件 %s 安装成功!' % name, 'data': output}
442
- return {'code': -1, 'msg': '软件 %s 安装失败:%s' % (name, output)}
441
+ return {'code': 0, 'msg': f'软件 {name} 安装成功!', 'data': output}
442
+ return {'code': -1, 'msg': f'软件 {name} 安装失败:{output}'}
443
443
 
444
444
 
445
445
  # ==================================================================
@@ -475,7 +475,7 @@ def web_handler(context, action):
475
475
  elif action == 'install':
476
476
  context.write(install_package(source))
477
477
 
478
- # --- 镜像源管理 ---
478
+ # --- 镜像站管理 ---
479
479
  elif action == 'mirrors':
480
480
  context.write({'code': 0, 'msg': '', 'data': get_mirrors()})
481
481
 
@@ -495,11 +495,11 @@ def web_handler(context, action):
495
495
  return
496
496
  sources.append({'name': source_name, 'url': url, 'builtin': False})
497
497
  _save_sources_config(sources)
498
- context.write({'code': 0, 'msg': 'APT 镜像源已添加:%s' % url})
498
+ context.write({'code': 0, 'msg': f'APT 镜像站已添加:{url}'})
499
499
 
500
500
  elif action == 'mirror-del':
501
501
  if not source:
502
- context.write({'code': -1, 'msg': '镜像源名称不能为空!'})
502
+ context.write({'code': -1, 'msg': '镜像站名称不能为空!'})
503
503
  return
504
504
  sources = _load_sources_config()
505
505
  found = None
@@ -508,17 +508,17 @@ def web_handler(context, action):
508
508
  found = s
509
509
  break
510
510
  if found is None:
511
- context.write({'code': -1, 'msg': '镜像源不存在!'})
511
+ context.write({'code': -1, 'msg': '镜像站不存在!'})
512
512
  return
513
513
  if found.get('builtin'):
514
- context.write({'code': -1, 'msg': '内置镜像源不可删除!'})
514
+ context.write({'code': -1, 'msg': '内置镜像站不可删除!'})
515
515
  return
516
516
  sources = [s for s in sources if s['name'] != source]
517
517
  _save_sources_config(sources)
518
- context.write({'code': 0, 'msg': '镜像源「%s」已删除' % source})
518
+ context.write({'code': 0, 'msg': f'镜像站「{source}」已删除'})
519
519
 
520
520
  elif action == 'switch':
521
- """切换镜像源:替换已有 .list 文件中 deb URL 的域名"""
521
+ """切换镜像站:替换已有 .list 文件中 deb URL 的域名"""
522
522
  url = context.get_argument('url', '').strip()
523
523
  source_name = context.get_argument('name', '') or context.get_argument('source', '')
524
524
  if not url and not source_name:
@@ -531,7 +531,7 @@ def web_handler(context, action):
531
531
  url = s['url']
532
532
  break
533
533
  if not url:
534
- context.write({'code': -1, 'msg': '未找到该镜像源的地址!'})
534
+ context.write({'code': -1, 'msg': '未找到该镜像站的地址!'})
535
535
  return
536
536
 
537
537
  new_url = url.rstrip('/')
@@ -578,7 +578,7 @@ def web_handler(context, action):
578
578
  pass
579
579
 
580
580
  if modified_count > 0:
581
- context.write({'code': 0, 'msg': 'APT 镜像源已切换至:%s(修改了 %d 个源文件)' % (source_name or url, modified_count)})
581
+ context.write({'code': 0, 'msg': f'APT 镜像站已切换至:{source_name or url}(修改了 {modified_count} 个源文件)'})
582
582
  else:
583
583
  context.write({'code': -1, 'msg': '没有找到需要切换的源文件'})
584
584
 
@@ -598,9 +598,9 @@ def web_handler(context, action):
598
598
  repo_file = 'sources.list.d/' + repo_file
599
599
 
600
600
  if item_exists(repo_file):
601
- context.write({'code': -1, 'msg': '仓库文件「%s」已存在!' % repo_file})
601
+ context.write({'code': -1, 'msg': f'仓库文件「{repo_file}」已存在!'})
602
602
  elif add_item(repo_file, {'content': content}) is True:
603
- context.write({'code': 0, 'msg': '仓库「%s」添加成功!' % repo_file})
603
+ context.write({'code': 0, 'msg': f'仓库「{repo_file}」添加成功!'})
604
604
  else:
605
605
  context.write({'code': -1, 'msg': '仓库添加失败!'})
606
606
 
@@ -625,7 +625,7 @@ def web_handler(context, action):
625
625
  elif not item_exists(source):
626
626
  context.write({'code': -1, 'msg': '仓库文件不存在!'})
627
627
  elif del_item(source):
628
- context.write({'code': 0, 'msg': '仓库「%s」已删除' % source})
628
+ context.write({'code': 0, 'msg': f'仓库「{source}」已删除'})
629
629
  else:
630
630
  context.write({'code': -1, 'msg': '仓库删除失败!'})
631
631
 
@@ -642,7 +642,7 @@ def web_handler(context, action):
642
642
  content = generate_sources(sources)
643
643
  context.write({'code': 0, 'msg': '', 'data': {'content': content}})
644
644
 
645
- # --- 第三方专用源 ---
645
+ # --- 第三方软件仓库 ---
646
646
  elif action == 'third_party':
647
647
  context.write(_get_apt_third_party())
648
648
 
@@ -655,14 +655,14 @@ def web_handler(context, action):
655
655
 
656
656
 
657
657
  # ==================================================================
658
- # APT 第三方专用源
658
+ # APT 第三方软件仓库
659
659
  # ==================================================================
660
660
 
661
661
  _APT_THIRD_PARTY_CACHE = None
662
662
 
663
663
 
664
664
  def _load_apt_third_party():
665
- """加载第三方专用源配置文件"""
665
+ """加载第三方软件仓库配置文件"""
666
666
  global _APT_THIRD_PARTY_CACHE
667
667
  if _APT_THIRD_PARTY_CACHE is not None:
668
668
  return _APT_THIRD_PARTY_CACHE
@@ -689,7 +689,7 @@ def _get_installed_list_files():
689
689
 
690
690
 
691
691
  def _get_apt_third_party():
692
- """获取适配 Debian/Ubuntu 的第三方专用源列表"""
692
+ """获取适配 Debian/Ubuntu 的第三方软件仓库列表"""
693
693
  sources = _load_apt_third_party()
694
694
  installed_files = _get_installed_list_files()
695
695
 
@@ -724,7 +724,7 @@ def _get_apt_third_party():
724
724
 
725
725
 
726
726
  def _install_apt_third_party(source_id):
727
- """安装 APT 第三方专用源"""
727
+ """安装 APT 第三方软件仓库"""
728
728
  sources = _load_apt_third_party()
729
729
  source = None
730
730
  for s in sources:
@@ -732,11 +732,11 @@ def _install_apt_third_party(source_id):
732
732
  source = s
733
733
  break
734
734
  if not source:
735
- return {'code': -1, 'msg': '第三方专用源不存在!'}
735
+ return {'code': -1, 'msg': '第三方软件仓库不存在!'}
736
736
 
737
737
  platforms = source.get('platform', [])
738
738
  if 'debian' not in platforms:
739
- return {'code': -1, 'msg': '该第三方专用源不支持当前系统平台!'}
739
+ return {'code': -1, 'msg': '该第三方软件仓库不支持当前系统平台!'}
740
740
 
741
741
  debian_cfg = source.get('debian', {})
742
742
  repo_file = debian_cfg.get('repo_file', source.get('repo_file', ''))
@@ -744,7 +744,7 @@ def _install_apt_third_party(source_id):
744
744
  gpgkey_url = debian_cfg.get('gpgkey', source.get('gpgkey', ''))
745
745
 
746
746
  if not repo_file:
747
- return {'code': -1, 'msg': '第三方专用源配置信息不完整!'}
747
+ return {'code': -1, 'msg': '第三方软件仓库配置信息不完整!'}
748
748
 
749
749
  # 对于有现成安装命令的源,使用专用函数
750
750
  source_id_lower = source_id.lower()
@@ -771,16 +771,16 @@ def _install_apt_third_party(source_id):
771
771
 
772
772
  # 通用安装:使用 repo_line 写入 .list 文件
773
773
  if not repo_line:
774
- return {'code': -1, 'msg': '该第三方专用源暂无自动安装脚本,请手动添加源配置!'}
774
+ return {'code': -1, 'msg': '该第三方软件仓库暂无自动安装脚本,请手动添加源配置!'}
775
775
 
776
776
  # 下载 GPG key
777
777
  if gpgkey_url:
778
778
  keyring_name = source_id.replace('-', '_') + '.gpg'
779
779
  keyring_path = '/usr/share/keyrings/' + keyring_name
780
780
  status, output = getstatusoutput(
781
- 'curl -fsSL %s | gpg --dearmor -o %s 2>&1' % (gpgkey_url, keyring_path))
781
+ f'curl -fsSL {gpgkey_url} | gpg --dearmor -o {keyring_path} 2>&1')
782
782
  if status != 0:
783
- return {'code': -1, 'msg': 'GPG 密钥下载失败:%s' % output}
783
+ return {'code': -1, 'msg': f'GPG 密钥下载失败:{output}'}
784
784
 
785
785
  # 写入 .list 文件
786
786
  list_path = str(Path(sources_list_d_path) / repo_file)
@@ -791,13 +791,13 @@ def _install_apt_third_party(source_id):
791
791
  with open(list_path, 'w', encoding='utf-8') as f:
792
792
  f.write(repo_line + '\n')
793
793
  except Exception as e:
794
- return {'code': -1, 'msg': '写入源文件失败:%s' % str(e)}
794
+ return {'code': -1, 'msg': f'写入源文件失败:{e!s}'}
795
795
 
796
796
  # apt update
797
797
  status, output = getstatusoutput('apt-get update 2>&1')
798
798
  if status == 0:
799
- return {'code': 0, 'msg': '第三方专用源「%s」安装成功!' % source['name']}
800
- return {'code': -1, 'msg': 'apt update 失败:%s' % output}
799
+ return {'code': 0, 'msg': f"第三方软件仓库「{source['name']}」安装成功!"}
800
+ return {'code': -1, 'msg': f'apt update 失败:{output}'}
801
801
 
802
802
 
803
803
  def _exec_apt_install_cmds(cmds, repo_name):
@@ -805,8 +805,8 @@ def _exec_apt_install_cmds(cmds, repo_name):
805
805
  for cmd in cmds:
806
806
  status, output = getstatusoutput(cmd + ' 2>&1')
807
807
  if status != 0:
808
- return {'code': -1, 'msg': '仓库「%s」安装失败:%s' % (repo_name, output)}
809
- return {'code': 0, 'msg': '仓库「%s」安装成功!' % repo_name}
808
+ return {'code': -1, 'msg': f'仓库「{repo_name}」安装失败:{output}'}
809
+ return {'code': 0, 'msg': f'仓库「{repo_name}」安装成功!'}
810
810
 
811
811
 
812
812
  if __name__ == '__main__':