|
11 | 11 | from app.models.stats import Period, UserUsageStatsList |
12 | 12 | from app.models.user import SubscriptionUserResponse, UsersResponseWithInbounds |
13 | 13 | from app.settings import subscription_settings |
14 | | -from app.subscription.share import encode_title, generate_subscription |
| 14 | +from app.subscription.share import encode_title, generate_subscription, setup_format_variables |
15 | 15 | from app.templates import render_template |
16 | 16 | from config import SUBSCRIPTION_PAGE_TEMPLATE |
17 | 17 |
|
@@ -58,16 +58,32 @@ def create_response_headers(user: UsersResponseWithInbounds, request_url: str, s |
58 | 58 | if user.expire: |
59 | 59 | user_info["expire"] = int(user.expire.timestamp()) |
60 | 60 |
|
| 61 | + # Setup format variables for dynamic title |
| 62 | + format_variables = setup_format_variables(user) |
| 63 | + |
| 64 | + # Get profile title and format it with variables |
| 65 | + profile_title = ( |
| 66 | + user.admin.profile_title |
| 67 | + if user.admin and user.admin.profile_title |
| 68 | + else sub_settings.profile_title |
| 69 | + ) |
| 70 | + |
| 71 | + # Format profile title with dynamic variables (same as host remark) |
| 72 | + if profile_title: |
| 73 | + try: |
| 74 | + profile_title = profile_title.format_map(format_variables) |
| 75 | + except (ValueError, KeyError): |
| 76 | + # If formatting fails (e.g., invalid format string), use original title |
| 77 | + pass |
| 78 | + |
61 | 79 | # Create and return headers |
62 | 80 | return { |
63 | 81 | "content-disposition": f'attachment; filename="{user.username}"', |
64 | 82 | "profile-web-page-url": request_url, |
65 | 83 | "support-url": user.admin.support_url |
66 | 84 | if user.admin and user.admin.support_url |
67 | 85 | else sub_settings.support_url, |
68 | | - "profile-title": encode_title(user.admin.profile_title) |
69 | | - if user.admin and user.admin.profile_title |
70 | | - else encode_title(sub_settings.profile_title), |
| 86 | + "profile-title": encode_title(profile_title) if profile_title else encode_title("Subscription"), |
71 | 87 | "profile-update-interval": str(sub_settings.update_interval), |
72 | 88 | "subscription-userinfo": "; ".join(f"{key}={val}" for key, val in user_info.items()), |
73 | 89 | } |
@@ -98,9 +114,9 @@ async def user_subscription( |
98 | 114 | # Handle HTML request (subscription page) |
99 | 115 | sub_settings: SubSettings = await subscription_settings() |
100 | 116 | db_user = await self.get_validated_sub(db, token) |
101 | | - response_headers = self.create_response_headers(db_user, request_url, sub_settings) |
102 | | - |
103 | 117 | user = await self.validated_user(db_user) |
| 118 | + |
| 119 | + response_headers = self.create_response_headers(user, request_url, sub_settings) |
104 | 120 |
|
105 | 121 | if "text/html" in accept_header: |
106 | 122 | template = ( |
@@ -141,9 +157,9 @@ async def user_subscription_with_client_type( |
141 | 157 | if client_type == ConfigFormat.block or not getattr(sub_settings.manual_sub_request, client_type): |
142 | 158 | await self.raise_error(message="Client not supported", code=406) |
143 | 159 | db_user = await self.get_validated_sub(db, token=token) |
144 | | - response_headers = self.create_response_headers(db_user, request_url, sub_settings) |
145 | | - |
146 | 160 | user = await self.validated_user(db_user) |
| 161 | + |
| 162 | + response_headers = self.create_response_headers(user, request_url, sub_settings) |
147 | 163 | conf, media_type = await self.fetch_config(user, client_type) |
148 | 164 |
|
149 | 165 | # Create response headers |
|
0 commit comments