Skip to content

Commit

Permalink
♻️ 将配置文件改为动态渲染,不使用缓存
Browse files Browse the repository at this point in the history
  • Loading branch information
Well2333 committed Jul 25, 2023
1 parent fcf910a commit cff0858
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 51 deletions.
8 changes: 1 addition & 7 deletions LiteClashProMan/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ def main():
# check dirs and files
static_dir = Path(__file__).parent.joinpath("static")
data_dir = Path("data")
profile_dir = data_dir.joinpath("profile")
provider_dir = data_dir.joinpath("provider")
template_dir = data_dir.joinpath("template")

for dir in [data_dir, profile_dir, provider_dir, template_dir]:
for dir in [data_dir, provider_dir, template_dir]:
if not dir.exists():
dir.mkdir(0o755, parents=True, exist_ok=True)
assert dir.is_dir(), f"{dir.as_posix()} should be folder"
Expand All @@ -29,11 +28,6 @@ def main():
static_dir.joinpath("template"), template_dir, dirs_exist_ok=True
)

# remove old profiles
if any(profile_dir.glob("*")):
shutil.rmtree(profile_dir)
profile_dir.mkdir(0o755, parents=True, exist_ok=True)

Config.load(Path(args.config))

from .main import main as run_main
Expand Down
16 changes: 7 additions & 9 deletions LiteClashProMan/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
from fastapi import FastAPI, HTTPException, Request
from fastapi.staticfiles import StaticFiles
from loguru import logger
from starlette.responses import FileResponse
from starlette.responses import PlainTextResponse
from uvicorn import Config, Server

from .config import config
from .log import LOGGING_CONFIG
from .subscribe import counter, update
from .subscribe import counter, update_provider, generate_profile

if config.sentry_dsn:
import sentry_sdk
Expand Down Expand Up @@ -44,22 +44,20 @@ async def profile(request: Request, path: str, id: str = None):
f"A request from {id}({user_ip}) to download profile {path} was received"
)

resp = FileResponse(
path=f"data/profile/{path}",
resp = PlainTextResponse(
content=await generate_profile(path[:-5]), headers=config.headers.copy()
)
counter_info = await counter(path[:-5])
if counter_info:
resp.headers["subscription-userinfo"] = counter_info
for h in config.headers:
resp.headers[h] = config.headers[h]
return resp


# manual update trigger
@app.get(f"/{config.urlprefix}/update")
async def _():
logger.info("Update is triggered manually")
error = await update()
error = await update_provider()
return str(error) or "update complete"


Expand All @@ -71,15 +69,15 @@ async def trigger_error():

@app.on_event("startup")
async def startup_event():
error = await update()
error = await update_provider()
if error:
raise error
logger.info(
f"Starting up scheduler from crontab {config.update_cron} at timezone {config.update_tz}"
)
scheduler = AsyncIOScheduler()
scheduler.add_job(
update, CronTrigger.from_crontab(config.update_cron, config.update_tz)
update_provider, CronTrigger.from_crontab(config.update_cron, config.update_tz)
)
scheduler.start()
logger.info(
Expand Down
22 changes: 7 additions & 15 deletions LiteClashProMan/model/clash/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import Dict, List, Literal, Optional, Union
from typing import Dict, List, Literal, Optional, Union, Sequence

import yaml
from pydantic import BaseModel, Extra, Field, validator
Expand Down Expand Up @@ -37,10 +37,12 @@ def render(
for group in self.proxy_groups:
if group.proxies == "__proxies_name_list__":
group.proxies = proxies_name_list
if isinstance(group.proxies, list):
if "__proxies_name_list__" in group.proxies:
group.proxies.remove("__proxies_name_list__")
group.proxies += proxies_name_list
if (
isinstance(group.proxies, Sequence)
and "__proxies_name_list__" in group.proxies
):
group.proxies.remove("__proxies_name_list__")
group.proxies += proxies_name_list
proxy_groups.append(group)

self.proxies = proxies
Expand All @@ -51,13 +53,3 @@ def render(
class Clash(ClashTemplate):
proxies: List[Union[SS, SSR, Vmess, Socks5, Snell, Trojan]]
proxy_groups: List[ProxyGroup] = Field(alias="proxy-groups")

def save(self, file: str) -> None:
Path(f"data/profile/{file}.yaml").write_text(
yaml.dump(
self.dict(exclude_none=True, by_alias=True, exclude_unset=True),
sort_keys=False,
allow_unicode=True,
),
encoding="utf-8",
)
53 changes: 34 additions & 19 deletions LiteClashProMan/subscribe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from pathlib import Path
from typing import List, Union

import yaml
from loguru import logger

from ..config import config
Expand All @@ -23,29 +25,42 @@ async def _subs(
return proxies


async def update():
logger.info("Start update profiles")
async def generate_profile(profile: str):
proxies = await _subs(config.profiles[profile].subs)
logger.debug(
f"Generating profile {profile} from template {config.profiles[profile].template}"
)
template = ClashTemplate.load(config.profiles[profile].template)
clash = template.render(proxies)
if clash.rule_providers:
for provider in clash.rule_providers:
# if provider is exists in local
# replace it with loacl file
if Path(f"data/provider/{provider}.yaml").exists():
clash.rule_providers[provider].url = "/".join(
[
config.domian,
config.urlprefix,
"provider",
f"{provider}.yaml",
]
)
return yaml.dump(
clash.model_dump(exclude_none=True, by_alias=True, exclude_unset=True),
sort_keys=False,
allow_unicode=True,
)


async def update_provider():
logger.info("Start update provider")
try:
rulesets = {}
for profile in config.profiles:
proxies = await _subs(config.profiles[profile].subs)
logger.debug(
f"Generating profile {profile} from template {config.profiles[profile].template}"
)
template = ClashTemplate.load(config.profiles[profile].template)
clash = template.render(proxies)
if clash.rule_providers:
for provider in clash.rule_providers:
rulesets[provider] = clash.rule_providers[provider].url
clash.rule_providers[provider].url = "/".join(
[
config.domian,
config.urlprefix,
"provider",
f"{provider}.yaml",
]
)
clash.save(profile)
if template.rule_providers:
for provider in template.rule_providers:
rulesets[provider] = template.rule_providers[provider].url
await Download.provider(rulesets)
logger.success("Update complete")

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

[project]
name = "LiteClashProMan"
version = "0.3.0"
version = "0.4.0"
description = "生成并更新 clash 配置文件,并提供 http 下载和规则文件镜像下载。"
authors = [
{name = "Well404", email = "[email protected]"},
Expand Down

0 comments on commit cff0858

Please sign in to comment.