20 Commits

Author SHA1 Message Date
星光-k
863e9b2f5d Add files via upload 2025-01-17 02:40:52 +00:00
星光-k
d523a31006 Add files via upload 2025-01-17 02:40:26 +00:00
星光-k
9d4895fca4 Add files via upload 2025-01-17 02:02:59 +00:00
星光-k
e7f71c699e Add files via upload 2025-01-17 02:02:07 +00:00
星光-k
419f44be7e Add files via upload 2025-01-17 02:01:40 +00:00
星光-k
6c90e54728 Update clean.py 2025-01-17 07:08:49 +08:00
星光-k
e70b05a529 Update main.py 2025-01-17 07:08:17 +08:00
星光-k
d8c12f7ad3 Update weather.py 2025-01-17 07:07:49 +08:00
星光-k
8eb21afb19 更新 weather.py 2025-01-16 20:15:21 +00:00
星光-k
7bc892d06b 更新 weather.py 2025-01-16 20:06:11 +00:00
星光-k
ca67499854 更新 weather.py 2025-01-16 19:17:51 +00:00
星光-k
0b5623d5f6 更新 main.py 2025-01-16 19:17:20 +00:00
星光-k
7a71514224 Add files via upload 2025-01-16 12:09:19 +00:00
星光-k
fac4c591fb 更新 install.sh 2025-01-16 11:55:34 +00:00
星光-k
95e6bb12be Add files via upload 2025-01-16 11:54:01 +00:00
星光-k
57ea23a6fa Update app.py 2025-01-16 19:53:20 +08:00
星光-k
5262d729fb Add files via upload 2025-01-16 11:52:16 +00:00
星光-k
428d056e58 Create index.html 2025-01-16 19:51:13 +08:00
星光-k
066d9676f3 Add files via upload 2025-01-16 11:50:31 +00:00
星光-k
54bb2ccf21 Create app.py 2025-01-16 19:50:01 +08:00
11 changed files with 1464 additions and 49 deletions

79
app/app.py Normal file
View File

@@ -0,0 +1,79 @@
from flask import Flask, render_template, request, send_from_directory, redirect, url_for, jsonify
import os
import re
import subprocess
app = Flask(__name__, template_folder='webui', static_url_path='', static_folder='webui')
FONT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'pic') # 字体文件夹路径
MAIN_PY_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'bin', 'main.py')
def list_font_files(font_dir):
try:
return os.listdir(font_dir)
except Exception as e:
print(f"Error listing font files: {e}")
return [] # 返回空列表以避免迭代错误
@app.route('/execute-shell')
def execute_shell():
# 替换以下命令为您想要执行的Shell命令
command = "sudo reboot now"
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
return jsonify({'status': 'success', 'output': result.stdout})
else:
return jsonify({'status': 'error', 'output': result.stderr})
@app.route('/edit_main_py')
def edit_main_py():
try:
with open(MAIN_PY_PATH, 'r') as file:
content = file.read()
except Exception as e:
return f"Error reading main.py: {e}", 500
return render_template('edit_main_py.html', content=content)
@app.route('/save_main_py', methods=['POST'])
def save_main_py():
new_content = request.form.get('content')
if new_content is None:
return "No content provided", 400
try:
with open(MAIN_PY_PATH, 'w') as file:
file.write(new_content)
except Exception as e:
return f"Error saving main.py: {e}", 500
return redirect(url_for('index'))
@app.route('/')
def index():
font_files = list_font_files(FONT_DIR)
return render_template('index.html', font_files=font_files)
@app.route('/upload', methods=['POST'])
def upload():
if 'font_file' not in request.files:
return '没有文件部分'
file = request.files['font_file']
if file.filename == '':
return '没有选择文件'
if file:
filename = os.path.join(FONT_DIR, file.filename)
file.save(filename)
return '文件已上传成功'
@app.route('/update_font_names')
def update_font_names():
font_files = list_font_files(FONT_DIR)
return render_template('update_font_names.html', font_files=font_files)
@app.route('/fonts/<filename>')
def fonts(filename):
return send_from_directory(FONT_DIR, filename)
if not os.path.exists(FONT_DIR):
os.makedirs(FONT_DIR)
if __name__ == '__main__':
# 绑定到0.0.0.0,允许远程访问
app.run(host='0.0.0.0', port=80, debug=False)

9
app/webui/default.min.css vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
Theme: Default
Description: Original highlight.js style
Author: (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
Maintainer: @highlightjs/core-team
Website: https://highlightjs.org/
License: see project LICENSE
Touched: 2021
*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}

View File

@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑 main.py</title>
<!-- 引用本地的highlight.js CSS -->
<link rel="stylesheet" href="{{ url_for('static', filename='default.min.css') }}">
</head>
<body>
<h1>编辑 main.py</h1>
<!-- 添加一个表单来提交编辑后的代码 -->
<form method="post" action="{{ url_for('save_main_py') }}">
<pre style="background-color: black !important;"><code class="python" id="code">{{ content }}</code></pre>
<input type="hidden" name="content" id="hidden-content">
<input type="submit" value="保存">
</form>
<!-- 引用本地的highlight.js JavaScript -->
<script src="{{ url_for('static', filename='highlight.min.js') }}"></script>
<script>
// 初始化highlight.js
document.addEventListener('DOMContentLoaded', (event) => {
hljs.highlightAll();
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var preElements = document.querySelectorAll('pre.code-editor');
preElements.forEach(function(pre) {
pre.style.backgroundColor = 'black';
});
});
</script>
<h2>重启</h2>
</head>
<body>
<button id="executeShellBtn">重启</button>
<script>
document.getElementById('executeShellBtn').addEventListener('click', function() {
fetch('/execute-shell')
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
alert('Command executed successfully:\n' + data.output);
} else {
alert('Error executing command:\n' + data.output);
}
})
.catch(error => {
alert('Error: ' + error);
});
});
</script>
</body>
</html>
 

1213
app/webui/highlight.min.js vendored Normal file

File diff suppressed because one or more lines are too long

27
app/webui/index.html Normal file
View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>字体上传和管理</title>
</head>
<body>
<h1>上传字体文件</h1>
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="font_file">
<input type="submit" value="上传">
</form>
<h2>已上传的字体文件:</h2>
<ul>
{% for font_file in font_files %}
<li>{{ font_file }}</li>
{% else %}
<li>没有找到字体文件。</li>
{% endfor %}
</ul>
<!-- 添加跳转到edit_main_py的按钮 -->
<a href="/edit_main_py"><button>编辑main.py</button></a>
</body>
</html>

View File

@@ -0,0 +1,26 @@
<!-- update_font_names.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>更新字体文件名</title>
</head>
<body>
<h1>更新字体文件名</h1>
<form method="post" action="/save_font_names">
<label for="font01">字体文件名 01:</label>
<input type="text" id="font01" name="font01"><br>
<label for="font02">字体文件名 02:</label>
<input type="text" id="font02" name="font02"><br>
<label for="font03">字体文件名 03:</label>
<input type="text" id="font03" name="font03"><br>
<label for="font04">字体文件名 04:</label>
<input type="text" id="font04" name="font04"><br>
<label for="font05">字体文件名 05:</label>
<input type="text" id="font05" name="font05"><br>
<label for="font06">字体文件名 06:</label>
<input type="text" id="font06" name="font06"><br>
<input type="submit" value="保存">
</form>
</body>
</html>

View File

@@ -48,7 +48,7 @@ def clear_screen():
logging.info(e)
except KeyboardInterrupt:
logging.info("按下了 Ctrl+C,正在退出")
logging.info("检测到键盘中断,正在退出")
epd2in13_V4.epdconfig.module_exit(cleanup=True)
exit()

View File

@@ -215,7 +215,7 @@ install_packages() {
# 安装pip包函数
install_pip_packages() {
echo "正在安装pip软件包"
if ! sudo pip3 install -i "$PIPY_MIRROR" spidev borax pillow requests; then
if ! sudo pip3 install -i "$PIPY_MIRROR" spidev borax pillow requests Flask; then
echo "pip软件包安装失败如果是最新版系统或是非lite系统" >&2
echo "请手动运行sudo pip3 install -i "$PIPY_MIRROR" spidev borax pillow requests --break-system-packages" >&2
exit 1

View File

@@ -86,7 +86,7 @@ def Bottom_edge(): #在图片中添加底边内容
local_addr= Get_ipv4_address() #获取当前IP地址
draw.text((10,107),"IP:"+local_addr,font = font05,fill =255)#显示当前IP地址
def Weather(): #在图片中添加天气内容
Weather_json = open('weather.json','r')
Weather_json = open('/root/2.13-Ink-screen-clock/bin/weather.json','r')
Weather_data = Weather_json.read()
Weather_json.close()
Weather_text=json.loads(Weather_data)
@@ -157,7 +157,7 @@ def Partial_refresh():#局刷函数
local_addr=local_addr1
Local_strong_brush() #局部强刷
'''天气局部更新函数'''
Weather_json = open('weather.json','r')
Weather_json = open('/root/2.13-Ink-screen-clock/bin/weather.json','r')
Weather_data = Weather_json.read()
Weather_json.close()
Weather_text=json.loads(Weather_data)
@@ -229,10 +229,10 @@ try:
epd.init()
epd.Clear(0xFF)
epd.sleep()
except IOError as e:
except OSError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("检测到键盘中断,正在优雅地退出")
logging.info("检测到键盘中断,正在清理并退出")
epd.init()
epd.Clear(0xFF) # 清除屏幕内容
epd.sleep() # 使屏幕进入休眠状态
@@ -252,4 +252,4 @@ epd.init()
epd.Clear(0xFF) # 清除屏幕内容
epd.sleep() # 使屏幕进入休眠状态
epd2in13_V4.epdconfig.module_exit() # 清理资源
exit()
exit()

View File

@@ -1,8 +1,10 @@
#!/bin/bash
f_name=main.py
f1_name=weather.py
f2_name=app.py
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
logdir="${dir%/*}/log"
appdir="${dir%/*}/app"
# 确保日志目录存在
mkdir -p "${logdir}"
pid=`ps -ef |grep $dir/$f_name | grep -v grep |awk '{print $2}'`
@@ -12,3 +14,4 @@ do
done
nohup /usr/bin/python3 -u $dir/$f_name > $logdir/info.log 2>&1 &
nohup /usr/bin/python3 -u $dir/$f1_name > $logdir/info-wenter.log 2>&1 &
nohup /usr/bin/python3 -u $appdir/$f2_name > $logdir/info-app.log 2>&1 &

View File

@@ -17,49 +17,48 @@ if os.path.exists(libdir):
sys.path.append(libdir) # 将引入文件添加到环境变量
def get_area_id(city_name):
"""从city.js中检索AREAID"""
"""从city.js中检索AREAID,无限重试直到成功"""
url = "https://j.i8tq.com/weather2020/search/city.js"
try:
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
# 直接打印原始数据
logging.debug("Raw data from city.js: %s", response.text)
# 预处理返回的数据去除非JSON部分
city_data_text = response.text.strip()
city_data_text = city_data_text.split('var city_data = ')[-1].rstrip(';')
if city_data_text:
city_data = json.loads(city_data_text)
# 遍历数据结构,查找城市名称
for province, cities in city_data.items():
for city, districts in cities.items():
for district, info in districts.items():
if info['NAMECN'] == city_name:
return info['AREAID']
logging.error("城市名称 '%s' 在城市数据中未找到,将使用默认城市信息", city_name)
else:
logging.error("从city.js接收到的数据为空")
except requests.RequestException as e:
logging.error("检索城市数据时发生网络错误: %s", e)
except json.JSONDecodeError as e:
logging.error("解析城市数据时发生JSON解码错误: %s", e)
return None
while True:
try:
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
# 直接打印原始数据
logging.debug("Raw data from city.js: %s", response.text)
# 预处理返回的数据去除非JSON部分
city_data_text = response.text.strip()
city_data_text = city_data_text.split('var city_data = ')[-1].rstrip(';')
if city_data_text:
city_data = json.loads(city_data_text)
# 遍历数据结构,查找城市名称
for province, cities in city_data.items():
for city, districts in cities.items():
for district, info in districts.items():
if info['NAMECN'] == city_name:
return info['AREAID']
logging.error("城市名称 '%s' 在城市数据中未找到,将使用默认城市信息", city_name)
else:
logging.error("从city.js接收到的数据为空")
except (requests.RequestException, json.JSONDecodeError) as e:
logging.error("检索或解析城市数据时发生错误: %s", e)
time.sleep(5) # 重试前等待5秒
def get_current_city():
"""获取当前城市名称"""
"""获取当前城市名称,无限重试直到成功"""
url = "http://ip-api.com/json/?lang=zh-CN"
try:
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
data = response.json()
if data['status'] == 'success':
return data['city']
else:
logging.error("获取当前城市失败: %s", data['message'])
except requests.RequestException as e:
logging.error("检索当前城市时出现网络错误: %s", e)
except json.JSONDecodeError as e:
logging.error("解析当前城市数据时出现JSON解码错误: %s", e)
return None
while True:
try:
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
data = response.json()
if data['status'] == 'success':
return data['city']
else:
logging.error("获取当前城市失败: %s", data['message'])
except (requests.RequestException, json.JSONDecodeError) as e:
logging.error("检索或解析当前城市时出现错误: %s", e)
time.sleep(5) # 重试前等待5秒
# 注意:无限重试可能会在特定情况下导致程序无法终止,请确保在实际使用中考虑适当的退出条件或限制重试次数。
def getWeath(city='101060101'):
headers = {
@@ -76,7 +75,7 @@ def getWeath(city='101060101'):
response.raise_for_status() # 检查请求是否成功
response.encoding = 'utf-8'
Weath = response.text[11:]
fileHandle = open('weather.json', 'w')
fileHandle = open('/root/2.13-Ink-screen-clock/bin/weather.json', 'w')
fileHandle.write(str(Weath))
fileHandle.close()
Timer(180, getWeath).start() # 定时器函数,间隔三分钟下载文件至本地
@@ -91,10 +90,10 @@ try:
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("检测到键盘中断,正在优雅地退出")
logging.info("检测到键盘中断,正在退出")
except Exception as e:
logging.error("发生了意外错误: %s", e)
exit()
# 脚本正常结束后的清理操作
exit()
exit()