Skip to content

Commit 863583b

Browse files
committed
feat: update interval
1 parent f69f388 commit 863583b

File tree

14 files changed

+91
-59
lines changed

14 files changed

+91
-59
lines changed

Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ ENV APP_WORKDIR=$APP_WORKDIR
3535
ENV APP_HOST="http://localhost"
3636
ENV APP_PORT=8000
3737
ENV PATH="/.venv/bin:/usr/local/nginx/sbin:$PATH"
38-
ENV UPDATE_CRON="0 22,10 * * *"
3938

4039
WORKDIR $APP_WORKDIR
4140

@@ -48,7 +47,7 @@ RUN mkdir -p /var/log/nginx && \
4847
ln -sf /dev/stdout /var/log/nginx/access.log && \
4948
ln -sf /dev/stderr /var/log/nginx/error.log
5049

51-
RUN apk update && apk add --no-cache dcron ffmpeg pcre
50+
RUN apk update && apk add --no-cache ffmpeg pcre
5251

5352
EXPOSE $APP_PORT 8080 1935
5453

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ https://raw.githubusercontent.com/Guovin/iptv-api/gd/source.json
176176
| subscribe_num | 结果中偏好的订阅源接口数量 | 10 |
177177
| time_zone | 时区,可用于控制更新时间显示的时区,可选值:Asia/Shanghai 或其它时区编码 | Asia/Shanghai |
178178
| urls_limit | 单个频道接口数量 | 10 |
179+
| update_interval | 定时执行更新时间间隔,单位小时,设置0或空则只运行一次,不作用于工作流 | 12 |
179180
| update_time_position | 更新时间显示位置,需要开启 open_update_time 才能生效,可选值:top、bottom,top: 显示于结果顶部,bottom: 显示于结果底部 | top |
180181

181182
## 快速上手
@@ -251,11 +252,10 @@ docker run -d -p 8000:8000 guovern/iptv-api
251252

252253
##### 环境变量:
253254

254-
| 变量 | 描述 | 默认值 |
255-
|:------------|:-------------------|:-------------------|
256-
| APP_HOST | 服务host地址,可修改使用公网域名 | "http://localhost" |
257-
| APP_PORT | 服务端口 | 8000 |
258-
| UPDATE_CRON | 定时任务执行时间 | "0 22,10 * * *" |
255+
| 变量 | 描述 | 默认值 |
256+
|:---------|:-------------------|:-------------------|
257+
| APP_HOST | 服务host地址,可修改使用公网域名 | "http://localhost" |
258+
| APP_PORT | 服务端口 | 8000 |
259259

260260
#### 3. 更新结果
261261

README_en.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ https://raw.githubusercontent.com/Guovin/iptv-api/gd/source.json
181181
| subscribe_num | The number of preferred subscribe source interfaces in the results | 10 |
182182
| time_zone | Time zone, can be used to control the time zone displayed by the update time, optional values: Asia/Shanghai or other time zone codes | Asia/Shanghai |
183183
| urls_limit | Number of interfaces per channel | 10 |
184+
| update_interval | Scheduled execution update interval, unit hours, set 0 or empty means run only once, does not apply to workflow | 12 |
184185
| update_time_position | Update time display position, need to enable open_update_time to take effect, optional values: top, bottom, top: display at the top of the result, bottom: display at the bottom of the result | top |
185186

186187
## Quick Start
@@ -259,11 +260,10 @@ Taking the host path /etc/docker as an example:
259260

260261
##### Environment Variables:
261262

262-
| Variable | Description | Default Value |
263-
|:------------|:---------------------|:-------------------|
264-
| APP_HOST | Service host address | "http://localhost" |
265-
| APP_PORT | Service port | 8000 |
266-
| UPDATE_CRON | Scheduled task time | "0 22,10 * * *" |
263+
| Variable | Description | Default Value |
264+
|:---------|:---------------------|:-------------------|
265+
| APP_HOST | Service host address | "http://localhost" |
266+
| APP_PORT | Service port | 8000 |
267267

268268
#### 3. Update Results
269269

config/config.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,7 @@ subscribe_num = 10
119119
time_zone = Asia/Shanghai
120120
# 单个频道接口数量 | Number of interfaces per channel
121121
urls_limit = 10
122+
# 定时执行更新时间间隔,单位小时,设置0或空则只运行一次,不作用于工作流,默认值: 12 | Scheduled execution update interval, unit hours, set 0 or empty means run only once, does not apply to workflow, default value: 12
123+
update_interval = 12
122124
# 更新时间显示位置,需要开启 open_update_time 才能生效,可选值:top、bottom,top: 显示于结果顶部,bottom: 显示于结果底部 | Update time display position, need to enable open_update_time to take effect, optional values: top, bottom, top: display at the top of the result, bottom: display at the bottom of the result
123125
update_time_position = top

docs/config.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,5 @@
5959
| subscribe_num | 结果中偏好的订阅源接口数量 | 10 |
6060
| time_zone | 时区,可用于控制更新时间显示的时区,可选值:Asia/Shanghai 或其它时区编码 | Asia/Shanghai |
6161
| urls_limit | 单个频道接口数量 | 10 |
62+
| update_interval | 定时执行更新时间间隔,单位小时,设置0或空则只运行一次,不作用于工作流 | 12 |
6263
| update_time_position | 更新时间显示位置,需要开启 open_update_time 才能生效,可选值:top、bottom,top: 显示于结果顶部,bottom: 显示于结果底部 | top |

docs/config_en.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,5 @@
5959
| subscribe_num | The number of preferred subscribe source interfaces in the results | 10 |
6060
| time_zone | Time zone, can be used to control the time zone displayed by the update time, optional values: Asia/Shanghai or other time zone codes | Asia/Shanghai |
6161
| urls_limit | Number of interfaces per channel | 10 |
62+
| update_interval | Scheduled execution update interval, unit hours, set 0 or empty means run only once, does not apply to workflow | 12 |
6263
| update_time_position | Update time display position, need to enable open_update_time to take effect, optional values: top, bottom, top: display at the top of the result, bottom: display at the bottom of the result | top |

docs/tutorial.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,10 @@ docker run -d -p 8000:8000 guovern/iptv-api
313313
314314
#### 环境变量:
315315

316-
| 变量 | 描述 | 默认值 |
317-
|:------------|:---------|:-------------------|
318-
| APP_HOST | 服务host地址 | "http://localhost" |
319-
| APP_PORT | 服务端口 | 8000 |
320-
| UPDATE_CRON | 定时任务执行时间 | "0 22,10 * * *" |
316+
| 变量 | 描述 | 默认值 |
317+
|:---------|:---------|:-------------------|
318+
| APP_HOST | 服务host地址 | "http://localhost" |
319+
| APP_PORT | 服务端口 | 8000 |
321320

322321
### 3. 更新结果
323322

docs/tutorial_en.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,10 @@ Taking the host path /etc/docker as an example:
358358
359359
#### Environment Variables:
360360

361-
| Variable | Description | Default Value |
362-
|:------------|:---------------------|:-------------------|
363-
| APP_HOST | Service host address | "http://localhost" |
364-
| APP_PORT | Service port | 8000 |
365-
| UPDATE_CRON | Scheduled task time | "0 22,10 * * *" |
361+
| Variable | Description | Default Value |
362+
|:---------|:---------------------|:-------------------|
363+
| APP_HOST | Service host address | "http://localhost" |
364+
| APP_PORT | Service port | 8000 |
366365

367366
### 3. Update Results
368367

entrypoint.sh

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,6 @@ done
1010

1111
. /.venv/bin/activate
1212

13-
crontab -d
14-
15-
if [ -n "$UPDATE_CRON" ]; then
16-
echo "$UPDATE_CRON cd $APP_WORKDIR && /.venv/bin/python main.py" | crontab -
17-
fi
18-
19-
# dcron log level
20-
# LOG_EMERG 0 [* system is unusable *]
21-
# LOG_ALERT 1 [* action must be taken immediately *]
22-
# LOG_CRIT 2 [* critical conditions *]
23-
# LOG_ERR 3 [* error conditions *]
24-
# LOG_WARNING 4 [* warning conditions *]
25-
# LOG_NOTICE 5 [* normal but significant condition *]
26-
# LOG_INFO 6 [* informational *]
27-
# LOG_DEBUG 7 [* debug-level messages *]
28-
29-
/usr/sbin/crond -b -L /tmp/dcron.log -l 4 &
30-
3113
nginx -g 'daemon off;' &
3214

3315
python $APP_WORKDIR/main.py &

main.py

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import asyncio
22
import copy
3+
import datetime
34
import gzip
45
import os
56
import pickle
67
from time import time
78

9+
import pytz
810
from tqdm import tqdm
911

1012
import utils.constants as constants
@@ -53,6 +55,9 @@ def __init__(self):
5355
self.pbar = None
5456
self.total = 0
5557
self.start_time = None
58+
self.stop_event = None
59+
self.ipv6_support = False
60+
self.now = None
5661

5762
async def visit_page(self, channel_names: list[str] = None):
5863
tasks_config = [
@@ -106,7 +111,6 @@ def pbar_update(self, name: str = "", item_name: str = ""):
106111

107112
async def main(self):
108113
try:
109-
user_final_file = config.final_file
110114
main_start_time = time()
111115
if config.open_update:
112116
self.channel_items = get_channel_items()
@@ -129,7 +133,6 @@ async def main(self):
129133
self.subscribe_result,
130134
self.online_search_result,
131135
)
132-
ipv6_support = config.ipv6_support or check_ipv6_support()
133136
cache_result = self.channel_data
134137
test_result = {}
135138
if config.open_speed_test:
@@ -139,7 +142,7 @@ async def main(self):
139142
test_data,
140143
seen=set(),
141144
filter_host=config.speed_test_filter_host,
142-
ipv6_support=ipv6_support
145+
ipv6_support=self.ipv6_support
143146
)
144147
self.total = get_urls_len(test_data)
145148
print(f"Total urls: {urls_total}, need to test speed: {self.total}")
@@ -151,7 +154,7 @@ async def main(self):
151154
self.pbar = tqdm(total=self.total, desc="Speed test")
152155
test_result = await test_speed(
153156
test_data,
154-
ipv6=ipv6_support,
157+
ipv6=self.ipv6_support,
155158
callback=lambda: self.pbar_update(name="测速", item_name="接口"),
156159
)
157160
cache_result = merge_objects(cache_result, test_result, match_key="url")
@@ -160,16 +163,13 @@ async def main(self):
160163
self.channel_data,
161164
result=test_result,
162165
filter_host=config.speed_test_filter_host,
163-
ipv6_support=ipv6_support
164-
)
165-
self.update_progress(
166-
f"正在生成结果文件",
167-
0,
166+
ipv6_support=self.ipv6_support
168167
)
168+
self.update_progress(f"正在生成结果文件", 0)
169169
write_channel_to_file(
170170
self.channel_data,
171171
epg=self.epg_result,
172-
ipv6=ipv6_support,
172+
ipv6=self.ipv6_support,
173173
first_channel_name=channel_names[0],
174174
)
175175
if config.open_history:
@@ -183,21 +183,22 @@ async def main(self):
183183
with gzip.open(constants.cache_path, "wb") as file:
184184
pickle.dump(cache_result, file)
185185
print(
186-
f"🥳 Update completed! Total time spent: {format_interval(time() - main_start_time)}. Please check the {user_final_file} file!"
186+
f"🥳 Update completed! Total time spent: {format_interval(time() - main_start_time)}."
187187
)
188188
if self.run_ui:
189189
open_service = config.open_service
190-
service_tip = ", 可使用以下地址进行观看:" if open_service else ""
190+
service_tip = ", 可使用以下地址进行观看" if open_service else ""
191191
tip = (
192192
f"✅ 服务启动成功{service_tip}"
193193
if open_service and config.open_update == False
194-
else f"🥳 更新完成, 耗时: {format_interval(time() - main_start_time)}, 请检查{user_final_file}文件{service_tip}"
194+
else f"🥳更新完成, 耗时: {format_interval(time() - main_start_time)}{service_tip}"
195195
)
196196
self.update_progress(
197197
tip,
198198
100,
199-
True,
199+
finished=True,
200200
url=f"{get_ip_address()}" if open_service else None,
201+
now=self.now
201202
)
202203
except asyncio.exceptions.CancelledError:
203204
print("Update cancelled!")
@@ -208,19 +209,39 @@ def default_callback(self, *args, **kwargs):
208209

209210
self.update_progress = callback or default_callback
210211
self.run_ui = True if callback else False
211-
await self.main()
212+
if self.run_ui:
213+
self.update_progress(f"正在检查网络是否支持IPv6", 0)
214+
self.ipv6_support = config.ipv6_support or check_ipv6_support()
215+
if not os.getenv("GITHUB_ACTIONS") and config.update_interval:
216+
await self.scheduler(asyncio.Event())
217+
else:
218+
await self.main()
212219

213220
def stop(self):
214221
for task in self.tasks:
215222
task.cancel()
216223
self.tasks = []
217224
if self.pbar:
218225
self.pbar.close()
226+
if self.stop_event:
227+
self.stop_event.set()
228+
229+
async def scheduler(self, stop_event):
230+
self.stop_event = stop_event
231+
while not stop_event.is_set():
232+
self.now = datetime.datetime.now(pytz.timezone(config.time_zone))
233+
await self.main()
234+
next_time = self.now + datetime.timedelta(hours=config.update_interval)
235+
print(f"🕒 Next update time: {next_time:%Y-%m-%d %H:%M:%S}")
236+
try:
237+
await asyncio.wait_for(stop_event.wait(), timeout=config.update_interval * 3600)
238+
except asyncio.TimeoutError:
239+
continue
219240

220241

221242
if __name__ == "__main__":
222243
info = get_version_info()
223-
print(f"ℹ️ {info['name']} Version: {info['version']}")
244+
print(f"✡️ {info['name']} Version: {info['version']}")
224245
loop = asyncio.new_event_loop()
225246
asyncio.set_event_loop(loop)
226247
update_source = UpdateSource()

0 commit comments

Comments
 (0)