diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml index 73d5720487..b0799ce9e0 100644 --- a/.github/ISSUE_TEMPLATE/1_bug.yml +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -1,47 +1,47 @@ -name: Bug report -description: Report a bug +name: Bug report | 报告运行错误或异常 +description: Submit a report about errors or exceptions to help us improve | 提交关于错误或异常的报告以帮助我们改进 +title: "[Bug]: " labels: [ bug ] body: - type: checkboxes attributes: - label: Don't skip these steps - description: Carefully complete the following steps before submitting an issue + label: Don't skip these steps | 不要跳过这些步骤 + description: Carefully complete the following steps before submitting an issue | 提交问题前,请仔细完成以下步骤 options: - - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field + - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field | 我明白,如果我“故意”删除或跳过任何强制性的\*字段,我将被**封锁** required: true - - label: I have checked through the search that there are no similar issues that already exist + - label: I have checked through the search that there are no similar issues that already exist | 我已经通过搜索仔细检查过没有存在已经创建的相似问题 required: true - - label: I will not submit any issues that are not related to this project + - label: I will not submit any issues that are not related to this project | 我不会提交任何与本项目无关的问题 required: true - type: checkboxes id: checklist attributes: - label: Occurrence environment + label: Occurrence environment | 触发环境 description: | - Please select what environment is the Bug triggered in: + Select the environment that the Bug triggers | 选择该Bug触发的环境: options: - - label: Workflow + - label: Workflow | 工作流 required: false - - label: GUI + - label: GUI | 软件 required: false - label: Docker required: false - - label: Command line + - label: Command line | 命令行 required: false - type: textarea id: description attributes: - label: Bug description - description: As for the specific description of the Bug, a good description will help to understand and solve it - placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible + label: Bug description | 具体描述 + description: As for the specific description of the Bug, a good description will help to understand and solve it | 对于Bug的具体描述,好的描述有助于理解和解决 + placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible | 提供任何附加信息,任何建议的解决方案,以及尽可能多的上下文和示例 validations: required: true - type: textarea id: log attributes: - label: Error log - description: Provides a detailed error log for the Bug - placeholder: Please enter a detailed error log - render: shell + label: Error log | 报错日志 + description: Provide detailed error logs of bugs, copy text or upload files as much as possible, do not take screenshots | 提供Bug的详细报错日志,尽量复制文本或上传文件,不要截图 + placeholder: Enter error logs or upload files | 输入报错日志或上传文件 validations: required: false diff --git a/.github/ISSUE_TEMPLATE/2_question.yml b/.github/ISSUE_TEMPLATE/2_question.yml deleted file mode 100644 index 361f9859ce..0000000000 --- a/.github/ISSUE_TEMPLATE/2_question.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Ask Question -description: Ask iptv-api related question -labels: [ question ] -body: - - type: checkboxes - attributes: - label: Don't skip these steps - description: Carefully complete the following steps before submitting an issue - options: - - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field - required: true - - label: I have checked through the search that there are no similar issues that already exist - required: true - - label: I will not submit any issues that are not related to this project - required: true - - type: checkboxes - id: checklist - attributes: - label: Occurrence environment - description: | - Select the context in which the question is located: - options: - - label: Workflow - required: false - - label: GUI - required: false - - label: Docker - required: false - - label: Command line - required: false - - type: textarea - id: description - attributes: - label: Question description - description: As for the specific description of the Question, a good description will help to understand and solve it - placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible - validations: - required: true - - type: textarea - id: log - attributes: - label: Related log - description: Provides detailed log for the question - placeholder: Please enter a detailed log - render: shell - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/3_enhancement.yml b/.github/ISSUE_TEMPLATE/3_enhancement.yml deleted file mode 100644 index 2585126939..0000000000 --- a/.github/ISSUE_TEMPLATE/3_enhancement.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Enhancement request -description: Request a feature enhancement -labels: [ enhancement ] -body: - - type: checkboxes - attributes: - label: Don't skip these steps - description: Carefully complete the following steps before submitting an issue - options: - - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field - required: true - - label: I have checked through the search that there are no similar issues that already exist - required: true - - label: I will not submit any issues that are not related to this project - required: true - - type: checkboxes - id: checklist - attributes: - label: Application environment - description: | - Select the context in which the enhancement is located: - options: - - label: Workflow - required: false - - label: GUI - required: false - - label: Docker - required: false - - label: Command line - required: false - - type: textarea - id: description - attributes: - label: Enhancement description - description: As for the specific description of the Enhancement, a good description will help to understand and solve it - placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible - validations: - required: true - - type: textarea - id: log - attributes: - label: Related log - description: Provides detailed log for the enhancement - placeholder: Please enter a detailed log - render: shell - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3ba13e0cec..22d858f305 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1 +1,9 @@ blank_issues_enabled: false +contact_links: + - name: Feature Suggestion | 功能建议 + url: https://github.com/Guovin/iptv-api/discussions/new?category=ideas + about: Share ideas for enhancements or new features | 建议改进或增加新功能 + + - name: Support and Help | 支持与帮助 + url: https://github.com/Guovin/iptv-api/discussions/categories/q-a + about: Please ask and answer questions here | 请在这里提问和答疑 \ No newline at end of file diff --git a/README.md b/README.md index 508ae522ee..319d924313 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,16 @@ - 接口源: +```bash +https://ghgo.xyz/raw.githubusercontent.com/Guovin/iptv-api/gd/output/result.m3u +``` + +```bash +https://ghgo.xyz/raw.githubusercontent.com/Guovin/iptv-api/gd/output/result.txt +``` + +或 + ```bash https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/output/result.m3u ``` @@ -120,6 +130,12 @@ https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/output/result.txt - 数据源: +```bash +https://ghgo.xyz/raw.githubusercontent.com/Guovin/iptv-api/gd/source.json +``` + +或 + ```bash https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/source.json ``` @@ -151,6 +167,7 @@ https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/source.json | open_url_info | 开启显示接口说明信息,用于控制是否显示分辨率、接口协议类型等信息,为$符号后的内容,播放软件使用该信息对接口进行描述 | True | | open_use_cache | 开启使用本地缓存数据,适用于查询请求失败场景(仅针对酒店源与组播源) | True | | open_use_old_result | 开启使用历史更新结果(包含模板与结果文件的接口),合并至本次更新中 | True | +| app_port | 页面服务端口,用于控制页面服务的端口号 | 8000 | | final_file | 生成结果文件路径 | output/result.txt | | hotel_num | 结果中偏好的酒店源接口数量 | 4 | | hotel_page_num | 酒店地区获取分页数量 | 1 | diff --git a/README_en.md b/README_en.md index 81b0ba6600..d48585addd 100644 --- a/README_en.md +++ b/README_en.md @@ -110,6 +110,16 @@ - Interface source: +```bash +https://ghgo.xyz/raw.githubusercontent.com/Guovin/iptv-api/gd/output/result.m3u +``` + +```bash +https://ghgo.xyz/raw.githubusercontent.com/Guovin/iptv-api/gd/output/result.txt +``` + +or + ```bash https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/output/result.m3u ``` @@ -120,6 +130,12 @@ https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/output/result.txt - Data source: +```bash +https://ghgo.xyz/raw.githubusercontent.com/Guovin/iptv-api/gd/source.json +``` + +or + ```bash https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/source.json ``` @@ -151,6 +167,7 @@ https://cdn.jsdelivr.net/gh/Guovin/iptv-api@gd/source.json | open_url_info | Enable display of API description information, used to control whether to show resolution, API protocol type, etc., the content after the $ symbol, playback software uses this information to describe the API | True | | open_use_cache | Enable the use of local cache data, applicable to the query request failure scenario (only for hotel sources and multicast sources) | True | | open_use_old_result | Enable the use of historical update results (including the interface for template and result files) and merge them into the current update | True | +| app_port | Page service port, used to control the port number of the page service | 8000 | | final_file | Generated result file path | output/result.txt | | hotel_num | The number of preferred hotel source interfaces in the results | 4 | | hotel_page_num | Number of pages to retrieve for hotel regions | 1 | diff --git a/config/config.ini b/config/config.ini index b71ba738b4..57a7989b4a 100644 --- a/config/config.ini +++ b/config/config.ini @@ -1,47 +1,95 @@ [Settings] +# 开启浏览器运行,若更新无数据可开启此模式,较消耗性能; 可选值: True, False | Enable browser execution, If there are no updates, this mode can be enabled, which consumes more performance; Optional values: True, False open_driver = False +# 开启无结果频道分类,自动归类至底部; 可选值: True, False | Enable empty category, automatically classified to the bottom; Optional values: True, False open_empty_category = False +# 开启分辨率过滤,低于最小分辨率(min_resolution)的接口将会被过滤; 可选值: True, False | Enable resolution filtering, interfaces below the minimum resolution (min_resolution) will be filtered; Optional values: True, False open_filter_resolution = True +# 开启速率过滤,低于最小速率(min_speed)的接口将会被过滤; 可选值: True, False | Enable rate filtering, interfaces below the minimum rate (min_speed) will be filtered; Optional values: True, False open_filter_speed = True +# 开启酒店源功能,关闭后所有酒店源工作模式都将关闭; 可选值: True, False | Enable hotel source function, after closing, all hotel source working modes will be closed; Optional values: True, False open_hotel = True +# 开启 Foodie 酒店源工作模式; 可选值: True, False | Enable Foodie hotel source working mode; Optional values: True, False open_hotel_foodie = True +# 开启 FOFA、ZoomEye 酒店源工作模式; 可选值: True, False | Enable FOFA, ZoomEye hotel source working mode; Optional values: True, False open_hotel_fofa = True +# 开启保留所有检索结果,会保留非模板频道名称的结果,推荐手动维护时开启; 可选值: True, False | Enable to keep all search results, will keep the results of non-template channel names, it is recommended to enable when manually maintaining; Optional values: True, False open_keep_all = False +# 开启转换生成 m3u 文件类型结果链接,支持显示频道图标; 可选值: True, False | Enable to convert and generate m3u file type result links, support display channel icons; Optional values: True, False open_m3u_result = True +# 开启组播源功能,关闭后所有组播源工作模式都将关闭; 可选值: True, False | Enable multicast source function, after closing, all multicast source working modes will be closed; Optional values: True, False open_multicast = True +# 开启 Foodie 组播源工作模式; 可选值: True, False | Enable Foodie multicast source working mode; Optional values: True, False open_multicast_foodie = True +# 开启 FOFA 组播源工作模式; 可选值: True, False | Enable FOFA multicast source working mode; Optional values: True, False open_multicast_fofa = True +# 开启关键字搜索源功能; 可选值: True, False | Enable keyword search source function; Optional values: True, False open_online_search = False +# 开启代理,自动获取免费可用代理,若更新无数据可开启此模式; 可选值: True, False | Enable proxy, automatically obtain free available proxy, If there are no updates, this mode can be enabled; Optional values: True, False open_proxy = False +# 开启查询请求,数据来源于网络(仅针对酒店源与组播源); 可选值: True, False | Enable query request, data comes from the network (only for hotel source and multicast source); Optional values: True, False open_request = False +# 开启页面服务,用于控制是否启动结果页面服务;如果使用青龙等平台部署,有专门设定的定时任务,需要更新完成后停止运行,可以关闭该功能; 可选值: True, False | Enable page service, used to control whether to start the result page service; If you use platforms such as Qinglong for deployment, there are special scheduled tasks, you need to stop running after the update is completed, you can turn off this function; Optional values: True, False open_service = True +# 开启排序功能(响应速度、日期、分辨率); 可选值: True, False | Enable sorting function (response speed, date, resolution); Optional values: True, False open_sort = True +# 开启订阅源功能; 可选值: True, False | Enable subscription source function; Optional values: True, False open_subscribe = True +# 开启更新,用于控制是否更新接口,若关闭则所有工作模式(获取接口和测速)均停止; 可选值: True, False | Enable update, used to control whether to update the interface, if closed, all working modes (get interface and speed measurement) will stop; Optional values: True, False open_update = True +# 开启显示更新时间; 可选值: True, False | Enable display update time; Optional values: True, False open_update_time = True +# 开启显示接口说明信息,用于控制是否显示分辨率、接口协议类型等信息,为$符号后的内容,播放软件使用该信息对接口进行描述; 可选值: True, False | Enable display interface description information, used to control whether to display resolution, interface protocol type and other information, the information after the $ symbol, the playback software uses this information to describe the interface; Optional values: True, False open_url_info = True +# 开启使用本地缓存数据,适用于查询请求失败场景(仅针对酒店源与组播源); 可选值: True, False | Enable to use local cached data, suitable for query request failure scenarios (only for hotel source and multicast source); Optional values: True, False open_use_cache = True +# 开启使用历史更新结果(包含模板与结果文件的接口),合并至本次更新中; 可选值: True, False | Enable to use historical update results (including interfaces of templates and result files), merged into this update; Optional values: True, False open_use_old_result = True +# 页面服务端口,用于控制页面服务的端口号; 默认值: 8000 | Page service port, used to control the port number of the page service; Default value: 8000 +app_port = 8000 +# 生成结果文件路径; 默认值: output/result.txt | Generate result file path; Default value: output/result.txt final_file = output/result.txt +# 结果中偏好的酒店源接口数量 | Preferred number of hotel source interfaces in the result hotel_num = 4 +# 酒店地区获取分页数量 | Number of hotel region acquisition pages hotel_page_num = 1 +# 酒店源地区列表,"全部"表示所有地区 | Hotel source region list, "all" means all regions hotel_region_list = 全部 +# 结果中偏好的 IPv4 接口数量 | Preferred number of IPv4 interfaces in the result ipv4_num = 5 +# 结果中偏好的 IPv6 接口数量 | Preferred number of IPv6 interfaces in the result ipv6_num = 5 +# 强制认为当前网络支持IPv6,跳过检测 | Force to consider that the current network supports IPv6, skip detection ipv6_support = False +# 生成结果中接口的协议类型,可选值:ipv4、ipv6、全部、all | Protocol type of the interface in the generated result, optional values: ipv4, ipv6, 全部, all ipv_type = 全部 +# 接口协议类型偏好,优先将该类型的接口排在结果前面,可选值:IPv4、IPv6、自动、auto | Interface protocol type preference, prefer to put this type of interface in front of the result, optional values: IPv4, IPv6, 自动, auto ipv_type_prefer = 自动 +# 接口最小分辨率,需要开启 open_filter_resolution 才能生效 | Minimum resolution of the interface, need to enable open_filter_resolution to take effect min_resolution = 1920x1080 +# 接口最小速率(单位M/s),需要开启 open_filter_speed 才能生效 | Minimum rate of the interface (unit M/s), need to enable open_filter_speed to take effect min_speed = 0.2 +# 结果中偏好的组播源接口数量 | Preferred number of multicast source interfaces in the result multicast_num = 3 +# 组播地区获取分页数量 | Number of multicast region acquisition pages multicast_page_num = 1 +# 组播源地区列表,"全部"表示所有地区 | Multicast source region list, "all" means all regions multicast_region_list = 全部 +# 结果中偏好的关键字搜索接口数量 | Preferred number of keyword search interfaces in the result online_search_num = 0 +# 关键字搜索频道获取分页数量 | Number of keyword search channel acquisition pages online_search_page_num = 1 +# 结果偏好的接口来源,结果优先按该顺序进行排序,hotel:酒店源,multicast:组播源,subscribe:订阅源,online_search:关键字搜索 | Preferred interface source of the result, the result is sorted in this order, hotel: hotel source, multicast: multicast source, subscribe: subscription source, online_search: keyword search origin_type_prefer = hotel,multicast,subscribe,online_search +# 获取最近时间范围内更新的接口(单位天),适当减小可避免出现匹配问题 | Get the interface updated within the recent time range (unit day), appropriately reducing can avoid matching problems recent_days = 30 +# 查询请求超时时长,单位秒(s),用于控制查询接口文本链接的超时时长以及重试时长,调整此值能优化更新时间 | Query request timeout duration, unit seconds (s), used to control the timeout duration and retry duration of querying the interface text link, adjusting this value can optimize the update time request_timeout = 10 +# 单个接口测速超时时长,单位秒(s);数值越大测速所属时间越长,能提高获取接口数量,但质量会有所下降;数值越小测速所需时间越短,能获取低延时的接口,质量较好;调整此值能优化更新时间 | Single interface speed measurement timeout duration, unit seconds (s); The larger the value, the longer the speed measurement time, which can increase the number of interfaces obtained, but the quality will decrease; The smaller the value, the shorter the speed measurement time, which can obtain interfaces with low latency and better quality; Adjusting this value can optimize the update time sort_timeout = 10 +# 模板文件路径, 默认值: config/demo.txt | Template file path, Default value: config/demo.txt source_file = config/demo.txt +# 结果中偏好的订阅源接口数量 | Preferred number of subscription source interfaces in the result subscribe_num = 3 +# 单个频道接口数量 | Number of interfaces per channel urls_limit = 10 \ No newline at end of file diff --git a/docs/config.md b/docs/config.md index fbb3767978..56faa46b28 100644 --- a/docs/config.md +++ b/docs/config.md @@ -23,6 +23,7 @@ | open_url_info | 开启显示接口说明信息,用于控制是否显示分辨率、接口协议类型等信息,为$符号后的内容,播放软件使用该信息对接口进行描述 | True | | open_use_cache | 开启使用本地缓存数据,适用于查询请求失败场景(仅针对酒店源与组播源) | True | | open_use_old_result | 开启使用历史更新结果(包含模板与结果文件的接口),合并至本次更新中 | True | +| app_port | 页面服务端口,用于控制页面服务的端口号 | 8000 | | final_file | 生成结果文件路径 | output/result.txt | | hotel_num | 结果中偏好的酒店源接口数量 | 4 | | hotel_page_num | 酒店地区获取分页数量 | 1 | diff --git a/docs/config_en.md b/docs/config_en.md index be2a6c17d7..d7aeef6538 100644 --- a/docs/config_en.md +++ b/docs/config_en.md @@ -23,6 +23,7 @@ | open_url_info | Enable display of API description information, used to control whether to show resolution, API protocol type, etc., the content after the $ symbol, playback software uses this information to describe the API | True | | open_use_cache | Enable the use of local cache data, applicable to the query request failure scenario (only for hotel sources and multicast sources) | True | | open_use_old_result | Enable the use of historical update results (including the interface for template and result files) and merge them into the current update | True | +| app_port | Page service port, used to control the port number of the page service | 8000 | | final_file | Generated result file path | output/result.txt | | hotel_num | The number of preferred hotel source interfaces in the results | 4 | | hotel_page_num | Number of pages to retrieve for hotel regions | 1 | diff --git a/service/app.py b/service/app.py index 7a8dd3616f..6bcac75cdf 100644 --- a/service/app.py +++ b/service/app.py @@ -4,6 +4,7 @@ sys.path.append(os.path.dirname(sys.path[0])) from flask import Flask, render_template_string from utils.tools import get_result_file_content, get_ip_address, resource_path +from utils.config import config import utils.constants as constants app = Flask(__name__) @@ -52,7 +53,7 @@ def run_service(): print(f"🚀 M3u api: {ip_address}/m3u") print(f"🚀 Txt api: {ip_address}/txt") print(f"✅ You can use this url to watch IPTV 📺: {ip_address}") - app.run(host="0.0.0.0", port=os.environ.get("APP_PORT") or 8000) + app.run(host="0.0.0.0", port=config.app_port) except Exception as e: print(f"❌ Service start failed: {e}") diff --git a/tkinter_ui/default.py b/tkinter_ui/default.py index 8462fb255a..1ac94ba588 100644 --- a/tkinter_ui/default.py +++ b/tkinter_ui/default.py @@ -93,6 +93,15 @@ def init_ui(self, root): ) self.open_service_checkbutton.pack(side=tk.LEFT, padx=4, pady=8) + self.app_port_label = tk.Label( + frame_default_open_update_column2, text="端口:", width=3 + ) + self.app_port_label.pack(side=tk.LEFT, padx=4, pady=8) + self.app_port_entry = tk.Entry(frame_default_open_update_column2, width=8) + self.app_port_entry.pack(side=tk.LEFT, padx=4, pady=8) + self.app_port_entry.insert(0, config.app_port) + self.app_port_entry.bind("", self.update_app_port) + frame_default_open_cache = tk.Frame(root) frame_default_open_cache.pack(fill=tk.X) frame_default_open_cache_column1 = tk.Frame(frame_default_open_cache) @@ -370,6 +379,9 @@ def update_open_update(self): def update_open_service(self): config.set("Settings", "open_service", str(self.open_update_var.get())) + def update_app_port(self, event): + config.set("Settings", "app_port", self.app_port_entry.get()) + def update_open_use_old_result(self): config.set( "Settings", "open_use_old_result", str(self.open_use_old_result_var.get()) @@ -452,6 +464,7 @@ def change_entry_state(self, state): for entry in [ "open_update_checkbutton", "open_service_checkbutton", + "app_port_entry", "open_use_old_result_checkbutton", "open_use_cache_checkbutton", "open_request_checkbutton", diff --git a/utils/config.py b/utils/config.py index d517184415..3fa985d3d1 100644 --- a/utils/config.py +++ b/utils/config.py @@ -299,6 +299,10 @@ def online_search_page_num(self): def open_empty_category(self): return self.config.getboolean("Settings", "open_empty_category", fallback=True) + @property + def app_port(self): + return os.environ.get("APP_PORT") or self.config.getint("Settings", "app_port", fallback=8000) + def load(self): """ Load the config diff --git a/utils/tools.py b/utils/tools.py index 203876d64d..54787f161b 100644 --- a/utils/tools.py +++ b/utils/tools.py @@ -336,14 +336,15 @@ def get_ip_address(): Get the IP address """ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + ip = "127.0.0.1" try: s.connect(("10.255.255.255", 1)) - IP = s.getsockname()[0] - except Exception: - IP = "127.0.0.1" + ip = s.getsockname()[0] + except: + ip = "127.0.0.1" finally: s.close() - return f"http://{IP}:{os.environ.get("APP_PORT") or 8000}" + return f"http://{ip}:{config.app_port}" def convert_to_m3u():