13 Commits

Author SHA1 Message Date
RTAkland
c8b2662d02 feat: update README.md 2021-12-18 21:58:56 +08:00
RTAkland
c69dedba45 feat: update requirements.txt 2021-12-18 21:54:55 +08:00
RTAkland
346b8c6289 feat: update .gitignore 2021-12-18 21:54:29 +08:00
RTAkland
35ff3d6e81 feat: removed test file 2021-12-18 21:53:57 +08:00
RTAkland
214ec5bf10 feat: update README.md 2021-12-18 21:53:34 +08:00
RTAkland
89c5ff2597 feat: update webserver 2021-12-18 21:41:59 +08:00
RTAkland
3b14691aea feat: change multiprocessing to concurrent 2021-12-18 21:41:24 +08:00
RTAkland
ae2cfce166 feat: change multiprocessing to concurrent 2021-12-18 21:40:48 +08:00
RTAkland
59f6561159 feat: removed something 2021-12-18 21:39:48 +08:00
RTAkland
95254ab80c feat: removed something 2021-12-18 21:39:14 +08:00
RTAkland
575de9463d feat: use high quality pictures 2021-12-18 21:38:29 +08:00
RTAkland
5db51f09fc feat: fixed a bug 2021-12-18 19:44:12 +08:00
RTAkland
b6577f1926 feat: update README.md 2021-12-18 17:16:48 +08:00
16 changed files with 375 additions and 50 deletions

2
.gitignore vendored
View File

@@ -1,7 +1,5 @@
*.yml *.yml
!config.yml !config.yml
*.token
*.zip
*.log *.log
*.log.* *.log.*
**/__pycache__ **/__pycache__

View File

@@ -8,8 +8,7 @@
import sys import sys
from core import qweather from core import qweather
from core.logger import Logger
if __name__ == '__main__': if __name__ == '__main__':
Logger.info('Start')
sys.exit(qweather.main()) sys.exit(qweather.main())

View File

@@ -1,7 +1,7 @@
<p align="center"> <p align="center">
<a href="https://github.com/MarkusJoe/QWeather"> <a href="https://github.com/MarkusJoe/QWeather">
<img src="https://img.shields.io/badge/Python-3.10.x-blue.svg" alt="PythonVersion"> <img src="https://img.shields.io/badge/Python-3.10.x-blue.svg" alt="PythonVersion">
<img src="https://img.shields.io/badge/release-3.0.1b-green.svg" alt="QWeatherVersion"> <img src="https://img.shields.io/badge/release-3.1.0b-green.svg" alt="QWeatherVersion">
<img src="https://img.shields.io/badge/LINCESE-Apache2.0-orange.svg" alt="LICENSE"> <img src="https://img.shields.io/badge/LINCESE-Apache2.0-orange.svg" alt="LICENSE">
</a> </a>
</p> </p>
@@ -20,7 +20,18 @@
<b><i><a href="https://markusjoe.github.io/" target="_blank">点击跳转到帮助文档</a></i></b> <b><i><a href="https://markusjoe.github.io/" target="_blank">点击跳转到帮助文档</a></i></b>
</div> </div>
## 问题汇总 ### 开源
- 本项目以[Apache-2.0](./LICENSE)许可开源, 即:
- 你可以直接使用该项目提供的功能, 无需任何授权
- 你可以在**注明来源版权信息**的情况下对源代码进行任意分发和修改以及衍生
### 已实现功能
- [x] 发送免费版&开发板右键
- [x] 间隔10分钟请求一次自然灾害预警信息
- [x] 在网页上快速查看天气
- [ ] ~~推送到QQ(咕咕咕)~~
### 问题汇总
#### Python 版本: #### Python 版本:
> 程序使用了Python3.10中的match-case语句 > 程序使用了Python3.10中的match-case语句
> 请使用Python3.10版本运行 > 请使用Python3.10版本运行
@@ -40,3 +51,13 @@
- 将config.yml正确填写完成 - 将config.yml正确填写完成
- 使用`pip/pip3 install -r requirements.txt` 安装需要的库 - 使用`pip/pip3 install -r requirements.txt` 安装需要的库
- 运行`QWeather.py` - 运行`QWeather.py`
### 网页上查看天气
- 将所有准备工作完成(能正常运行QWeather.py)
- 运行QWeather.py
- 打开浏览器输入***127.0.0.1***:7898 (127.0.0.1可以更改为部署本项目的服务器ip)
## 联系方式
- 邮箱: <markushammered@gmail.com>

View File

@@ -100,6 +100,11 @@ client-settings:
# 可选: "DEBUG" "INFO" "WARNING" "ERROR" "CRITICAL" # 可选: "DEBUG" "INFO" "WARNING" "ERROR" "CRITICAL"
level: DEBUG level: DEBUG
# [选填/只能一个] 开启本地网页快速查看天气
# 默认: False
# 可选: "True" "False"
webserver: False
# [标识/不填] 仅作用户读取标识 # [标识/不填] 仅作用户读取标识
only-view-settings: only-view-settings:

View File

@@ -15,7 +15,6 @@ from core.logger import Logger
from core.language import Language from core.language import Language
from core.read_config import read_config from core.read_config import read_config
Logger.info('Be imported')
settings = read_config() settings = read_config()

View File

@@ -9,12 +9,13 @@
import sys import sys
import time import time
import argparse import argparse
from concurrent.futures import ProcessPoolExecutor
from core.logger import Logger from core.logger import Logger
from core.language import Language from core.language import Language
from core.settings import change_settings from core.settings import change_settings
from lib import webserver
from core import read_config from core import read_config
from core.sendmail import Mail from core.sendmail import Mail
from multiprocessing import Process
def check_time(): def check_time():
@@ -72,8 +73,9 @@ def main():
Logger.debug(f'{language["debug_done"]}') Logger.debug(f'{language["debug_done"]}')
case _: case _:
pass pass
processes.submit(check_time)
Process(target=check_time).run() if settings[2]['webserver']:
processes.submit(webserver.process_request())
time_count = 0 time_count = 0
while True: while True:
@@ -87,6 +89,7 @@ def main():
if __name__ != '__main__': if __name__ != '__main__':
language = Language() language = Language()
settings = read_config() settings = read_config()
processes = ProcessPoolExecutor(max_workers=3)
Logger.info(f'{language["statement_1"]}') Logger.info(f'{language["statement_1"]}')
Logger.info(f'{language["statement_2"]}') Logger.info(f'{language["statement_2"]}')

View File

@@ -4,7 +4,3 @@
# @Development Tool: PyCharm # @Development Tool: PyCharm
# @Create Time: 2021/10/16 # @Create Time: 2021/10/16
# @File Name: __init__.py # @File Name: __init__.py
from core.logger import Logger
Logger.info('Be imported')

View File

@@ -10,17 +10,23 @@
启用等级: DEV 启用等级: DEV
""" """
from core.read_config import read_config
import requests import requests
import json import json
def hourly_weather(location: int, key: str, lang: str = 'zh', unit: str = 'm'): def hourly_weather():
settings = read_config()
location = settings[1]['location']
key = settings[1]['key']
lang = settings[1]['lang']
unit = settings[1]['unit']
r = requests.get( r = requests.get(
f'https://devapi.qweather.com/v7/weather/24h?location={location}&key={key}&lang={lang}&unit={unit}') f'https://devapi.qweather.com/v7/weather/24h?location={location}&key={key}&lang={lang}&unit={unit}')
data = json.loads(r.text) data = json.loads(r.text)
status_code = data['code'] status_code = data['code']
updateTime = str(data['updateTime'][:-6]).replace('T', '') updateTime = str(data['updateTime'][:-6])[10:].replace('T', '')
main_data = data['hourly'] # 24 main_data = data['hourly'] # 24
return status_code, updateTime, main_data return status_code, updateTime, main_data

View File

@@ -11,11 +11,17 @@
启用等级: DEV 启用等级: DEV
""" """
from core.read_config import read_config
import requests import requests
import json import json
def indices(location: int, key: str, lang: str = 'zh', unit: str = 'm'): def indices():
settings = read_config()
location = settings[1]['location']
key = settings[1]['key']
lang = settings[1]['lang']
unit = settings[1]['unit']
r = requests.get( r = requests.get(
f'https://devapi.qweather.com/v7/indices/1d?type=0&location={location}&key={key}&lang={lang}&unit={unit}') f'https://devapi.qweather.com/v7/indices/1d?type=0&location={location}&key={key}&lang={lang}&unit={unit}')
data = json.loads(r.text) data = json.loads(r.text)

View File

@@ -10,29 +10,20 @@
启用等级: DEV 启用等级: DEV
""" """
from core.read_config import read_config
import requests import requests
import json import json
import sys
from ruamel.yaml import YAML
def real_time_air_quality(): def real_time_air_quality():
yaml = YAML() settings = read_config()
with open(sys.path[1] + '/config.yml', 'r', encoding='utf-8') as f: location = settings[1]['location']
config = yaml.load(f.read()) key = settings[1]['key']
lang = settings[1]['lang']
unit = settings[1]['unit']
mode = config['request-settings']['mode'] r = requests.get(f'https://devapi.qweather.com/v7/air/now?'
key = config['request-settings']['key'] f'location={location}&key={key}&lang={lang}&unit={unit}&gzip=y')
location = config['request-settings']['location']
unit = config['request-settings']['unit']
lang = config['request-settings']['lang']
if mode != 'dev':
return False, print('Only Dev-mode')
session = requests.Session()
session.trust_env = False
r = session.get(f'https://devapi.qweather.com/v7/air/now?'
f'location={location}config.yml&key={key}&lang={lang}&unit={unit}&gzip=y')
_data = json.loads(r.text) _data = json.loads(r.text)
return _data['code'], _data['now'] return _data['now']

View File

@@ -10,18 +10,14 @@
启用等级: DEV 启用等级: DEV
""" """
from core.read_config import read_config
import requests import requests
import json import json
from ruamel.yaml import YAML
def get_warning_list(_range='cn'): def get_warning_list(_range='cn'):
yaml = YAML() settings = read_config()
with open('./config.yml', 'r', encoding='utf-8') as f: key = settings[1]['key']
config = yaml.load(f.read()) r = requests.get(f'https://devapi.qweather.com/v7/warning/list?range={_range}&key={key}')
key = config['request-settings']['key']
session = requests.Session()
session.trust_env = False
r = session.get(f'https://devapi.qweather.com/v7/warning/list?range={_range}&key={key}')
_data = json.loads(r.text) _data = json.loads(r.text)
return _data['code'], _data['warningLocList'][0]['locationId'] return _data['code'], _data['warningLocList'][0]['locationId']

312
lib/webserver.py Normal file
View File

@@ -0,0 +1,312 @@
#!/usr/bin/env python3
# -- coding:utf-8 --
# @Author: markushammered@gmail.com
# @Development Tool: PyCharm
# @Create Time: 2021/12/18
# @File Name: webserver.py
import socket
import sys
from core.logger import Logger
from core.read_config import read_config
from core.information import WeatherInfo
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 7898))
server.listen(5)
def build_html():
settings = read_config()
city = settings[3]['city-name']
mode = settings[1]['mode']
match mode:
case 'dev':
dev_weather = WeatherInfo().dev_version()
dates = dev_weather[0]
day_weathers = dev_weather[1]
night_weathers = dev_weather[2]
highest_temps = dev_weather[3]
lowest_temps = dev_weather[4]
icons = dev_weather[5]
sunset = dev_weather[6]
sunrise = dev_weather[7]
humidity = dev_weather[8]
wind_speed = dev_weather[9]
wind_scale = dev_weather[10]
wind_dir = dev_weather[11]
uv_index = dev_weather[12]
cloud = dev_weather[13]
pressure = dev_weather[14]
vis = dev_weather[15]
html = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p style="text-align: center"><i><b>地区:{city}</b></i></p>
<br />
<table style="border: 0; text-align: center; margin:0 auto">
<tr>
<th>|&nbsp;日期&nbsp;&nbsp;</th>
<th>|&nbsp;天气&nbsp;&nbsp;</th>
<th>|&nbsp;最低温度&nbsp;&nbsp;</th>
<th>|&nbsp;最高温度&nbsp;&nbsp;</th>
</tr>
<tr>
<!--日期 天气 最低 最高/Date Weather LowestTemp HighestTemp-->
<td>今天</td>
<td>{day_weathers[0]}<img src="./res/icons/{icons[0]}.png" width="20" alt="">/{night_weathers[0]}
<img src="./res/icons/{icons[1]}.png"
width="20" alt=""></td> <td>{lowest_temps[0]}℃</td>
<td>{highest_temps[0]}℃</td>
</tr>
<tr>
<td>{dates[1]}</td>
<td>{day_weathers[1]}<img src="./res/icons/{icons[2]}.png" width="20" alt="">/{night_weathers[1]}
<img src="./res/icons/{icons[3]}.png"
width="20" alt=""></td> <td>{lowest_temps[1]}℃</td>
<td>{highest_temps[1]}℃</td>
</tr>
<tr>
<td>{dates[2]}</td>
<td>{day_weathers[2]}<img src="./res/icons/{icons[4]}.png" width="20" alt="">/{night_weathers[2]}
<img src="./res/icons/{icons[5]}.png"
width="20" alt=""></td> <td>{lowest_temps[2]}℃</td>
<td>{highest_temps[2]}℃</td>
</tr>
<tr>
<td>{dates[3]}</td>
<td>{day_weathers[3]}<img src="./res/icons/{icons[6]}.png" width="20" alt="">/{night_weathers[3]}
<img src="./res/icons/{icons[7]}.png"
width="20" alt=""></td> <td>{lowest_temps[3]}℃</td>
<td>{highest_temps[3]}℃</td>
</tr>
<tr>
<td>{dates[4]}</td>
<td>{day_weathers[4]}<img src="./res/icons/{icons[8]}.png" width="20" alt="">/{night_weathers[4]}
<img src="./res/icons/{icons[9]}.png"
width="20" alt=""></td> <td>{lowest_temps[4]}℃</td>
<td>{highest_temps[4]}℃</td>
</tr>
<tr>
<td>{dates[5]}</td>
<td>{day_weathers[5]}<img src="./res/icons/{icons[10]}.png" width="20" alt="">/{night_weathers[5]}
<img src="./res/icons/{icons[11]}.png"
width="20" alt=""></td> <td>{lowest_temps[5]}℃</td>
<td>{highest_temps[5]}℃</td>
</tr>
<tr>
<td>{dates[6]}</td>
<td>{day_weathers[6]}<img src="./res/icons/{icons[12]}.png" width="20" alt="">/{night_weathers[6]}
<img src="./res/icons/{icons[13]}.png"
width="20" alt=""></td> <td>{lowest_temps[6]}℃</td>
<td>{highest_temps[6]}℃</td>
</tr>
</table>
<table style="border: 0;text-align: center; margin:0 auto">
<tr>
<th>&nbsp;</th>
</tr>
<tr>
<th>风速/风级/风向</th>
<th>相对湿度</th>
<th>紫外线</th>
</tr>
<tr>
<td>{wind_speed}m/s&nbsp; {wind_scale}&nbsp; {wind_dir}&nbsp;</td>
<td>{humidity}%&nbsp;</td>
<td>{uv_index}&nbsp;</td>
</tr>
<tr>
<th>&nbsp;</th>
</tr>
<tr>
<th>能见度</th>
<th>大气压强</th>
<th>相对云量</th>
</tr>
<tr>
<td>{vis}km&nbsp;</td>
<td>{pressure}hPa&nbsp;</td>
<td>{cloud}%&nbsp;</td>
</tr>
</table>
<table style="border: 0;text-align: center; margin:0 auto">
<tr>
<th>&nbsp;</th>
</tr>
<tr>
<td><img src="./res/basic-resources/sunrise.png" alt="Sunrise" width="30"></td>
<td>&nbsp;</td>
<td><img src="./res/basic-resources/sunset.png" alt="Sunset" width="30"></td>
</tr>
<tr>
<td>&nbsp;{sunrise}&nbsp;</td>
<td>---------------</td>
<td>&nbsp;{sunset}&nbsp;</td>
</tr>
</table>
<div style="text-align: center;" id="About">
<br />
<br />
<br />
<i>
<b>
<a href="https://dev.qweather.com/" style="color: black" target="_blank">QWeather</a>
<a style="color: black">&nbsp;·&nbsp;</a>
<a href="https://github.com/MarkusJoe/QWeather" style="color: black" target="_blank">Github Repo</a>
</b>
</i>
</div>
</body>
</html>"""
return html
case 'free':
dev_weather = WeatherInfo().free_version()
dates = dev_weather[0]
day_weathers = dev_weather[1]
night_weathers = dev_weather[2]
highest_temps = dev_weather[3]
lowest_temps = dev_weather[4]
icons = dev_weather[5]
sunset = dev_weather[6]
sunrise = dev_weather[7]
humidity = dev_weather[8]
wind_speed = dev_weather[9]
wind_scale = dev_weather[10]
wind_dir = dev_weather[11]
uv_index = dev_weather[12]
cloud = dev_weather[13]
pressure = dev_weather[14]
vis = dev_weather[15]
html = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p style="text-align: center"><i><b>地区:{city}</b></i></p>
<br />
<table style="border: 0; text-align: center; margin:0 auto">
<tr>
<th>|&nbsp;日期&nbsp;&nbsp;</th>
<th>|&nbsp;天气&nbsp;&nbsp;</th>
<th>|&nbsp;最低温度&nbsp;&nbsp;</th>
<th>|&nbsp;最高温度&nbsp;&nbsp;</th>
</tr>
<tr>
<!--日期 天气 最低 最高/Date Weather LowestTemp HighestTemp-->
<td>今天</td>
<td>{day_weathers[0]}<img src="./res/icons/{icons[0]}.png" width="20" alt="">/{night_weathers[0]}
<img src="./res/icons/{icons[1]}.png"
width="20" alt=""></td> <td>{lowest_temps[0]}℃</td>
<td>{highest_temps[0]}℃</td>
</tr>
<tr>
<td>{dates[1]}</td>
<td>{day_weathers[1]}<img src="./res/icons/{icons[2]}.png" width="20" alt="">/{night_weathers[1]}
<img src="./res/icons/{icons[3]}.png"
width="20" alt=""></td> <td>{lowest_temps[1]}℃</td>
<td>{highest_temps[1]}℃</td>
</tr>
<tr>
<td>{dates[2]}</td>
<td>{day_weathers[2]}<img src="./res/icons/{icons[4]}.png" width="20" alt="">/{night_weathers[2]}
<img src="./res/icons/{icons[5]}.png"
width="20" alt=""></td> <td>{lowest_temps[2]}℃</td>
<td>{highest_temps[2]}℃</td>
</table>
<table style="border: 0;text-align: center; margin:0 auto">
<tr>
<th>&nbsp;</th>
</tr>
<tr>
<th>风速/风级/风向</th>
<th>相对湿度</th>
<th>紫外线</th>
</tr>
<tr>
<td>{wind_speed}m/s&nbsp; {wind_scale}&nbsp; {wind_dir}&nbsp;</td>
<td>{humidity}%&nbsp;</td>
<td>{uv_index}&nbsp;</td>
</tr>
<tr>
<th>&nbsp;</th>
</tr>
<tr>
<th>能见度</th>
<th>大气压强</th>
<th>相对云量</th>
</tr>
<tr>
<td>{vis}km&nbsp;</td>
<td>{pressure}hPa&nbsp;</td>
<td>{cloud}%&nbsp;</td>
</tr>
</table>
<table style="border: 0;text-align: center; margin:0 auto">
<tr>
<th>&nbsp;</th>
</tr>
<tr>
<td><img src="./res/basic-resources/sunrise.png" alt="Sunrise" width="30"></td>
<td>&nbsp;</td>
<td><img src="./res/basic-resources/sunset.png" alt="Sunset" width="30"></td>
</tr>
<tr>
<td>&nbsp;{sunrise}&nbsp;</td>
<td>---------------</td>
<td>&nbsp;{sunset}&nbsp;</td>
</tr>
</table>
<div style="text-align: center;" id="About">
<br />
<br />
<br />
<i>
<b>
<a href="https://dev.qweather.com/" style="color: black" target="_blank">QWeather</a>
<a style="color: black">&nbsp;·&nbsp;</a>
<a href="https://github.com/MarkusJoe/QWeather" style="color: black" target="_blank">Github Repo</a>
</b>
</i>
</div>
</body>
</html>"""
return html
case _:
return "You hadn't selected a mode"
def process_request():
try:
while True:
c, a = server.accept()
data = str(c.recv(1024)).split(':')[0][6:][:-17]
html = build_html()
if data == '/':
c.send('HTTP1.1/ 200 OK\r\n\r\n'.encode('utf-8'))
c.send(html.encode('utf-8'))
Logger.info(f'{a}: Get {data} --by browser')
else:
try:
with open(f'.{data}', 'rb') as f:
c.send('HTTP1.1/ 200 OK\r\n\r\n'.encode('utf-8'))
c.send(f.read())
Logger.info(f'{a}: Get {data} --by browser')
except FileNotFoundError:
c.send(f'HTTP1.1/ 404 Not Found\r\n\r\n{html}'.encode('utf-8'))
c.close()
except BrokenPipeError:
Logger.critical('Link speed was too fast! Subprocess:webserver exited')
sys.exit(1)

View File

@@ -1,7 +1,4 @@
requests==2.26.0 requests==2.26.0
ruamel.yaml==0.17.17 ruamel.yaml==0.17.17
pandas==1.3.4 pandas==1.3.4
pyppeteer==0.2.6
bs4==0.0.1
openpyxl==3.0.9
colorlog==6.5.0 colorlog==6.5.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1005 B

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -4,7 +4,3 @@
# @Development Tool: PyCharm # @Development Tool: PyCharm
# @Create Time: 2021/11/7 # @Create Time: 2021/11/7
# @File Name: __init__.py.py # @File Name: __init__.py.py
from core.logger import Logger
Logger.info('Be imported')