Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v4.1.2 is ready for production #20

Merged
merged 8 commits into from
Feb 9, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
opt code
  • Loading branch information
zmisgod committed Jan 19, 2025
commit f3a9aa456cc57480cd95369fce58ab99ba537a0f
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
regex = "1"
actix-rt = "2.9.0"
actix-web = { version = "4.4.1", default-features = false, features = ["macros", "compress-gzip", "compress-brotli"] }
actix-files = "0.6.2"
Expand Down
31 changes: 31 additions & 0 deletions search.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"fetchSource": [
{
"urls": [
"https://github.com/YueChan/Live",
"https://github.com/YanG-1989/m3u",
"https://github.com/fanmingming/live",
"https://github.com/qwerttvv/Beijing-IPTV",
"https://github.com/joevess/IPTV",
"https://github.com/cymz6/AutoIPTV-Hotel"
],
"includeFiles": [],
"parseType": "github-home-page"
},
{
"urls": [
"https://github.com/iptv-org/iptv/tree/master/streams"
],
"includeFiles": [
"cn.m3u",
"tw.m3u",
"hk.m3u"
],
"parseType": "github-sub-page"
}
],
"validExtensions": [
".txt",
".m3u"
]
}
114 changes: 111 additions & 3 deletions src/common/m3u.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use crate::common::VideoType::Unknown;
use actix_rt::time;
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::{self, BufRead, Read, Write};
use std::io::{self, BufRead, Error, Read, Write};
use std::net::IpAddr;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::thread;
Expand Down Expand Up @@ -110,6 +111,10 @@ impl M3uObject {
self.name = name
}

pub fn get_url(&self) -> String {
self.url.clone()
}

pub fn set_search_name(&mut self, search_name: String) {
self.search_name = search_name.to_lowercase()
}
Expand All @@ -118,6 +123,18 @@ impl M3uObject {
self.raw = raw
}

pub fn generate_raw(&mut self) {
let mut tv_id = "".to_string();
let mut tv_logo = "".to_string();
let mut group_title = "".to_string();
if self.extend.is_some() {
tv_id = format!(" tvg-id=\"{}\"", self.extend.clone().unwrap().tv_id.clone());
tv_logo = format!(" tvg-logo=\"{}\"", self.extend.clone().unwrap().tv_id.clone());
group_title = format!(" group-title=\"{}\"", self.extend.clone().unwrap().tv_id.clone());
}
self.raw = format!("#EXTINF:-1 {}{}{},{}\n{}", tv_id, tv_logo, group_title, self.name, self.url);
}

pub fn set_extend(&mut self, extend: M3uExtend) {
self.extend = Some(extend)
}
Expand Down Expand Up @@ -232,6 +249,71 @@ impl M3uObjectList {
self.debug = debug
}

pub async fn search(&self, search_name: String, full_match: bool, ipv4: bool,
ipv6: bool, exclude_url: Vec<String>, exclude_host: Vec<String>) -> Result<Vec<M3uObject>, Error> {
let mut list = vec![];
let s_name = search_name.clone();
let exp_list: Vec<&str> = s_name.split(",").collect();
println!("query params ----{:?} search data count --- {}", exp_list, self.list.len());
for v in self.list.clone() {
let mut is_save = false;
for e in exp_list.clone() {
if full_match {
if v.search_name.eq(e.to_string().as_str()) {
is_save = true;
}
} else {
if v.search_name.contains(e.to_string().as_str()) {
is_save = true;
}
}
}
// let mut now_ip_type = 0;
// match v.url.clone().parse::<IpAddr>() {
// Ok(IpAddr::V4(_)) => {
// now_ip_type = 1; // ipv4
// }
// Ok(IpAddr::V6(_)) => {
// now_ip_type = 2; // ipv6
// }
// _ => {}
// }
// if now_ip_type == 0 {
// continue;
// }
// if now_ip_type == 1 && ipv4 {
// is_save = true
// } else if now_ip_type == 2 && ipv6 {
// is_save = true
// }
// for ex_url in exclude_url.clone() {
// if v.url.clone().to_lowercase().eq(&ex_url.clone().to_lowercase()) {
// is_save = false
// }
// }
// for ex_host in exclude_host.clone() {
// // 解析 URL
// let url = url::Url::parse(&*v.clone().url);
// match url {
// Ok(url) => {
// // 获取主机部分
// if let Some(host) = url.host_str() {
// if ex_host.clone().eq(&host.to_string()) {
// is_save = false;
// }
// }
// }
// _ => {}
// }
// }
if is_save {
list.push(v.clone());
}
}

Ok(list)
}

pub async fn check_data_new(&mut self, request_time: i32, _concurrent: i32, sort: bool, no_check: bool) {
let mut search_clarity = false;
match &self.search_clarity {
Expand Down Expand Up @@ -332,13 +414,39 @@ impl M3uObjectList {
}
self.set_counter(counter);
// 生成.m3u 文件
self.generate_m3u_file(output_file.clone(), lines);
self.generate_m3u_file_from_giving_list(output_file.clone(), lines);
// 生成.txt 文件
self.generate_text_file(output_file.clone());
time::sleep(Duration::from_millis(500)).await;
}

pub fn generate_m3u_file(&mut self, output_file: String, lines: Vec<String>) {
pub fn generate_m3u_file(&mut self, output_file: String) {
if self.list.len() > 0 {
let mut result_m3u_content: Vec<String> = vec![];
match &self.header {
None => result_m3u_content.push(String::from("#EXTM3U")),
Some(data) => {
if data.x_tv_url.len() > 0 {
let exp = data.x_tv_url.join(",");
let header_line = format!("#EXTM3U x-tvg-url=\"{}\"", exp);
result_m3u_content.push(header_line.to_owned());
} else {
result_m3u_content.push(String::from("#EXTM3U"))
}
}
}
for x in self.list.clone() {
result_m3u_content.push(x.raw.clone());
}
let mut fd = File::create(output_file.to_owned()).unwrap();
for x in result_m3u_content {
let _ = fd.write(format!("{}\n", x).as_bytes());
}
let _ = fd.flush();
}
}

pub fn generate_m3u_file_from_giving_list(&mut self, output_file: String, lines: Vec<String>) {
if lines.len() > 0 {
let mut result_m3u_content: Vec<String> = vec![];
match &self.header {
Expand Down
3 changes: 2 additions & 1 deletion src/common/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,12 @@ impl TaskManager {
pub fn update_task(&self, id: String, pass_task: TaskContent) -> Result<bool> {
let mut tasks = self.tasks.lock().unwrap();
if let Some(mut task) = tasks.get_mut(&id) {
let task_info = task.clone().get_task_info();
let mut task_info = task.clone().get_task_info();
let ori = pass_task.valid().unwrap();
let mut task = Task::new();
task.set_original(ori);
task.set_id(id);
task_info.set_run_type(pass_task.run_type);
task.set_task_info(task_info);
tasks.insert(task.get_uuid(), task.clone());
drop(tasks);
Expand Down
32 changes: 30 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod common;
mod utils;
mod web;
mod search;

use clap::{arg, Args as clapArgs, Parser, Subcommand};
use std::env;
use tempfile::tempdir;
use crate::common::do_check;
use crate::common::{do_check};
use crate::search::{do_search};

const DEFAULT_HTTP_PORT: u16 = 8089;

Expand All @@ -15,6 +17,19 @@ enum Commands {
Web(WebArgs),
/// 检查相关命令
Check(CheckArgs),
/// 搜索相关命令
Fetch(FetchArgs),
}

#[derive(clapArgs)]
pub struct FetchArgs {
/// 搜索频道名称,如果有别名,用英文逗号分隔
#[arg(long = "search", default_value_t = String::from(""))]
search: String,

/// 是否需要检测
#[arg(long = "check", default_value_t = false)]
check: bool,
}

#[derive(clapArgs)]
Expand Down Expand Up @@ -97,7 +112,7 @@ fn get_pid_file() -> String {
return a.to_owned();
}
}
return String::default();
String::default()
}

async fn start_daemonize_web(pid_name: &String, port: u16) {
Expand Down Expand Up @@ -152,5 +167,18 @@ pub async fn main() {
args.sort, args.no_check).await.unwrap();
}
}
Commands::Fetch(args) => {
if args.search.len() > 0 {
let data = do_search(args.search.clone(), args.check).await;
match data {
Ok(data) => {
println!("{:?}", data)
}
Err(e) => {
println!("获取失败---{}", e)
}
}
}
}
}
}
Loading