You've already forked QWeatherReporter
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
936dd14a87 | ||
|
|
21a7f9140d | ||
|
|
23f44c3f78 | ||
|
|
9477c33952 | ||
|
|
7fdd0d56a1 | ||
|
|
2117771518 | ||
|
|
ea4d04a71c | ||
|
|
235e252bab | ||
|
|
278913b2c3 | ||
|
|
3cc8afa1f4 | ||
|
|
3034346c73 | ||
|
|
7b4a0dd033 |
27
README.md
27
README.md
@@ -1,14 +1,14 @@
|
||||
<p align="center">
|
||||
<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/release-3.1.3b-green.svg" alt="QWeatherVersion">
|
||||
<img src="https://img.shields.io/badge/release-3.2.0-green.svg" alt="QWeatherVersion">
|
||||
<img src="https://img.shields.io/badge/LINCESE-Apache2.0-orange.svg" alt="LICENSE">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
|
||||
## *QWeather*
|
||||
## *QWeatherReporter*
|
||||
|
||||
<i style="text-align: center;"><a href="https://www.qweather.com/">QWeather Official Website</a></i>\
|
||||
<i style="text-align: center;"><a href="https://dev.qweather.com/">QWeather Development Platform</a></i>
|
||||
@@ -20,32 +20,32 @@
|
||||
<b><i><a href="https://markusjoe.github.io/" target="_blank">点击跳转到帮助文档</a></i></b>
|
||||
</div>
|
||||
|
||||
## 声明
|
||||
- > 程序作者: **RTAkland (markushammered@gmail.com)**
|
||||
- > 和风天气开发者平台:https://dev.qweather.com
|
||||
- > 和风天气官网: https://qweather.com
|
||||
|
||||
|
||||
### 开源
|
||||
- 本项目以[Apache-2.0](./LICENSE)许可开源, 即:
|
||||
- 你可以直接使用该项目提供的功能, 无需任何授权
|
||||
- 你可以在**注明来源版权信息**的情况下对源代码进行任意分发和修改以及衍生
|
||||
|
||||
### 已实现功能
|
||||
- [x] 发送免费版&开发板右键
|
||||
- [x] 发送免费版&开发版天气预报功能
|
||||
- [x] 间隔10分钟请求一次自然灾害预警信息
|
||||
- [x] 在网页上快速查看天气
|
||||
- [ ] ~~推送到QQ(咕咕咕)~~
|
||||
|
||||
### 问题汇总
|
||||
#### Python 版本:
|
||||
> 程序使用了Python3.10中的match-case语句
|
||||
> 请使用Python3.10版本运行
|
||||
> 程序使用了*Python3.10.x*中的match-case语句
|
||||
> 请使用*Python3.10.x*版本运行
|
||||
#### 主题选择:
|
||||
> 在2.9.0之后的版本不支持自定义天气图标 只能使用最新的图标
|
||||
#### 配置填写问题:
|
||||
> `location`项和`only-view-settings`类不需要用户填写, 只需要打开`QWeather.py`进行自助填写
|
||||
|
||||
|
||||
## 声明
|
||||
- > 程序作者: **RTAkland (markushammered@gmail.com)**
|
||||
- > 和风天气开发者平台:https://dev.qweather.com
|
||||
- > 和风天气官网: https://qweather.com
|
||||
|
||||
## 如何使用
|
||||
- 程序基于python3.10开发 务必使用python3.10版本运行
|
||||
- 将config.yml正确填写完成
|
||||
@@ -54,8 +54,9 @@
|
||||
|
||||
### 网页上查看天气
|
||||
- 将所有准备工作完成(能正常运行QWeather.py)
|
||||
- 运行QWeather.py
|
||||
- 打开浏览器输入***127.0.0.1***:7898 (127.0.0.1可以更改为部署本项目的服务器ip)
|
||||
- 运行`QWeather.py`
|
||||
- 打开浏览器输入**127.0.0.1:7898**
|
||||
>127.0.0.1可以更改为部署本项目的服务器ip, 7898端口不能被其他程序占用或不开放此端口
|
||||
|
||||
|
||||
## 联系方式
|
||||
|
||||
@@ -15,8 +15,7 @@ from core.language import Language
|
||||
from core.settings import change_settings
|
||||
from core.read_config import read_config
|
||||
from core.sendmail import Mail
|
||||
from lib.get_host_ip import get_host_ip
|
||||
from lib import webservice
|
||||
from lib.webservice import accept_requests
|
||||
|
||||
|
||||
def check_time():
|
||||
@@ -116,8 +115,8 @@ def main():
|
||||
|
||||
processes.submit(check_time)
|
||||
if settings[2]['webservice']:
|
||||
Logger.info(f'{language["webservice_ip"]}:{get_host_ip()}:7898')
|
||||
processes.submit(webservice.process_request())
|
||||
Logger.info(f'{language["webservice_ip"]}:127.0.0.1:7898')
|
||||
processes.submit(accept_requests())
|
||||
|
||||
time_count = 0
|
||||
while True:
|
||||
|
||||
@@ -16,6 +16,7 @@ from core.logger import Logger
|
||||
from core.language import Language
|
||||
from core.information import WeatherInfo
|
||||
from core.read_config import read_config
|
||||
from lib.hitokoto import hitokoto
|
||||
|
||||
|
||||
class Mail:
|
||||
@@ -33,6 +34,8 @@ class Mail:
|
||||
self.message['From'] = Header('QWeather') # 发件人名称
|
||||
self.message['To'] = Header('All allowed User') # 收件人显示名称
|
||||
|
||||
self.hitokoto = hitokoto() # 一言
|
||||
|
||||
if self.enableSSL:
|
||||
self.smtp = smtplib.SMTP_SSL(self.server, self.port) # 登录服务器 使用SSL连接
|
||||
else:
|
||||
@@ -128,8 +131,8 @@ class Mail:
|
||||
<th> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>风速/风级/风向</th>
|
||||
<th>相对湿度</th>
|
||||
<th>风速/级/向</th>
|
||||
<th>湿度</th>
|
||||
<th>紫外线</th>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -142,8 +145,8 @@ class Mail:
|
||||
</tr>
|
||||
<tr>
|
||||
<th>能见度</th>
|
||||
<th>大气压强</th>
|
||||
<th>相对云量</th>
|
||||
<th>压强</th>
|
||||
<th>云量</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{vis}km </td>
|
||||
@@ -166,9 +169,13 @@ class Mail:
|
||||
<td> {sunset} </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<div style="text-align: center" id="hitokoto">
|
||||
<p>
|
||||
{self.hitokoto}
|
||||
</p>
|
||||
</div>
|
||||
<div style="text-align: center;" id="About">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<i>
|
||||
<b>
|
||||
@@ -271,8 +278,8 @@ class Mail:
|
||||
<th> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>风速/风级/风向</th>
|
||||
<th>相对湿度</th>
|
||||
<th>风速/级/向</th>
|
||||
<th>湿度</th>
|
||||
<th>紫外线</th>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -285,8 +292,8 @@ class Mail:
|
||||
</tr>
|
||||
<tr>
|
||||
<th>能见度</th>
|
||||
<th>大气压强</th>
|
||||
<th>相对云量</th>
|
||||
<th>压强</th>
|
||||
<th>云量</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{vis}km </td>
|
||||
@@ -309,9 +316,13 @@ class Mail:
|
||||
<td> {sunset} </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<div style="text-align: center" id="hitokoto">
|
||||
<p>
|
||||
{self.hitokoto}
|
||||
</p>
|
||||
</div>
|
||||
<div style="text-align: center;" id="About">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<i>
|
||||
<b>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# -- coding:utf-8 --
|
||||
# @Author: markushammered@gmail.com
|
||||
# @Development Tool: PyCharm
|
||||
# @Create Time: 2021/12/21
|
||||
# @File Name: get_host_ip.py
|
||||
|
||||
import socket
|
||||
|
||||
|
||||
def get_host_ip():
|
||||
"""
|
||||
查询本机ip地址
|
||||
:return: ip
|
||||
"""
|
||||
ip_s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
ip_s.connect(('8.8.8.8', 80))
|
||||
ip = ip_s.getsockname()[0]
|
||||
ip_s.close()
|
||||
|
||||
return ip
|
||||
23
lib/hitokoto.py
Normal file
23
lib/hitokoto.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# -- coding:utf-8 --
|
||||
# @Author: markushammered@gmail.com
|
||||
# @Development Tool: PyCharm
|
||||
# @Create Time: 2021/12/24
|
||||
# @File Name: hitokoto.py
|
||||
|
||||
import requests
|
||||
from core.language import Language
|
||||
from core.logger import Logger
|
||||
|
||||
|
||||
def hitokoto():
|
||||
language = Language()
|
||||
url = 'https://v1.hitokoto.cn/'
|
||||
Logger.info(f'{language["hitokoto"]}')
|
||||
res = requests.get(url).json()
|
||||
speaker = res['from_who']
|
||||
text = res['hitokoto']
|
||||
if not speaker:
|
||||
speaker = language['noname']
|
||||
full_text = f'{text} --{speaker}'
|
||||
|
||||
return full_text
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
|
||||
import socket
|
||||
import sys
|
||||
import threading
|
||||
from core.logger import Logger
|
||||
from core.read_config import read_config
|
||||
from core.information import WeatherInfo
|
||||
@@ -15,7 +15,7 @@ from core.language import Language
|
||||
|
||||
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
server.bind(('localhost', 7898))
|
||||
server.bind(('127.0.0.1', 7898))
|
||||
server.listen(5)
|
||||
|
||||
language = Language()
|
||||
@@ -54,7 +54,7 @@ def build_html():
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<title>QWeather|网页查看天气服务</title>
|
||||
</head>
|
||||
<body>
|
||||
<p style="text-align: center"><i><b>地区:{city}</b></i></p>
|
||||
@@ -122,8 +122,8 @@ def build_html():
|
||||
<th> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>风速/风级/风向</th>
|
||||
<th>相对湿度</th>
|
||||
<th>风速/级/向</th>
|
||||
<th>湿度</th>
|
||||
<th>紫外线</th>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -136,8 +136,8 @@ def build_html():
|
||||
</tr>
|
||||
<tr>
|
||||
<th>能见度</th>
|
||||
<th>大气压强</th>
|
||||
<th>相对云量</th>
|
||||
<th>压强</th>
|
||||
<th>云量</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{vis}km </td>
|
||||
@@ -199,7 +199,7 @@ def build_html():
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<title>QWeather|网页查看天气服务</title>
|
||||
</head>
|
||||
<body>
|
||||
<p style="text-align: center"><i><b>地区:{city}</b></i></p>
|
||||
@@ -252,8 +252,8 @@ def build_html():
|
||||
</tr>
|
||||
<tr>
|
||||
<th>能见度</th>
|
||||
<th>大气压强</th>
|
||||
<th>相对云量</th>
|
||||
<th>压强</th>
|
||||
<th>云量</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{vis}km </td>
|
||||
@@ -295,32 +295,42 @@ def build_html():
|
||||
return "You hadn't selected a mode"
|
||||
|
||||
|
||||
def process_request():
|
||||
def process_requests(c, a):
|
||||
"""
|
||||
处理请求
|
||||
:param c: connection
|
||||
:param a: address
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
while True:
|
||||
c, a = server.accept()
|
||||
data = str(c.recv(1024)).split(':')[0][6:][:-17]
|
||||
html = build_html()
|
||||
if data == '/': # 判断用户请求的目标是否为根目录, 如果是则返回html; 如果不是则继续判断
|
||||
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()
|
||||
data = str(c.recv(1024)).split(':')[0][6:][:-17]
|
||||
html = build_html()
|
||||
if data == '/' or '': # 判断用户请求的目标是否为根目录, 如果是则返回html; 如果不是则继续判断
|
||||
c.sendto('HTTP1.1/ 200 OK\r\n\r\n'.encode('utf-8'), a)
|
||||
c.sendto(html.encode('utf-8'), a)
|
||||
Logger.info(f'{language["get_resource"]} {data} {language["get_resource_from"]} {a[0]}:{a[1]}')
|
||||
else: # 继续判断用户请求的文件是否存在
|
||||
try:
|
||||
with open(f'.{data}', 'rb') as f:
|
||||
c.sendto('HTTP1.1/ 200 OK\r\n\r\n'.encode('utf-8'), a)
|
||||
c.sendto(f.read(), a)
|
||||
Logger.info(f'{language["get_resource"]} {data} {language["get_resource_from"]} {a[0]}:{a[1]}')
|
||||
except FileNotFoundError:
|
||||
c.sendto(f'HTTP1.1/ 404 Not Found\r\n\r\n{html}'.encode('utf-8'), a)
|
||||
except BrokenPipeError:
|
||||
Logger.critical(f'{language["connection_speed_too_fast"]}')
|
||||
sys.exit(1)
|
||||
Logger.error(f'{language["connection_speed_too_fast"]}')
|
||||
except IOError:
|
||||
Logger.critical(f'{language["an_io_error"]}')
|
||||
sys.exit(1)
|
||||
Logger.error(f'{language["an_io_error"]}')
|
||||
finally:
|
||||
c.close()
|
||||
return
|
||||
|
||||
|
||||
def accept_requests():
|
||||
"""
|
||||
接受请求
|
||||
:return:
|
||||
"""
|
||||
while True:
|
||||
c, a = server.accept()
|
||||
threading.Thread(target=process_requests, args=(c, a,)).start()
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
"change_setting": "You are changing setting.",
|
||||
"exit": "Exited.",
|
||||
"webservice_ip": "Local webservice ip",
|
||||
"connection_speed_too_fast": "Connection speed is too fast, subprocess: webservice has exited.",
|
||||
"an_io_error": "An IO error."
|
||||
"connection_speed_too_fast": "Connection speed is too fast",
|
||||
"an_io_error": "An IO error.",
|
||||
"noname": "No name.",
|
||||
"hitokoto": "Get hitokoto successfully.",
|
||||
"get_resource": "Get resource",
|
||||
"get_resource_from": "from"
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
"change_setting": "更改设置",
|
||||
"exit": "已退出",
|
||||
"webservice_ip": "webservice地址",
|
||||
"connection_speed_too_fast": "连接速度过快, 子进程:webservice.py 已退出",
|
||||
"an_io_error": "一个IO错误"
|
||||
"connection_speed_too_fast": "连接速度过快",
|
||||
"an_io_error": "一个IO错误",
|
||||
"noname": "佚名",
|
||||
"hitokoto": "一言获取成功",
|
||||
"get_resource": "获取资源",
|
||||
"get_resource_from": "来自"
|
||||
}
|
||||
Reference in New Issue
Block a user