Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,8 @@ _Are you aware of any other fixer that isn't included here? Feel free to open an
- [EmbedEZ • bilibliez.com](https://embedez.com)
- [fxBilibili • fxbilibili.seria.moe](https://github.com/seriaati/fxBilibili)
- [BiliFix • vxbilibili.com](https://vxbilibili.com/) *Used by FixTweetBot*
- Other official public instances/redirects: `vxb23.tv`
- Rewrites `bilibili.com` to `vxbilibili.com` and `b23.tv` to `vxb23.tv`, preserving subdomains
- Supports BiliFix translation languages through the website settings
- <img src="assets/threads.webp" alt="Threads" height="20"/> Threads
- [FixThreads • official instance deprecated](https://github.com/milanmdev/fixthreads)
- Other unofficial public instances/redirects: `fixthreads.seria.moe` *Used by FixTweetBot*, `drhong.ddns.net:9813` (http only)
Expand Down
13 changes: 13 additions & 0 deletions database/migrations/2026_09_10_010000_add_bilifix_translation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""AddBilifixTranslation Migration."""

from masoniteorm.migrations import Migration


class AddBilifixTranslation(Migration):
def up(self):
with self.schema.table('guilds') as table:
table.boolean('bilibili_tr').default(False).after('bilibili')

def down(self):
with self.schema.table('guilds') as table:
table.drop_column('bilibili_tr')
24 changes: 22 additions & 2 deletions src/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from database.models.CustomWebsite import CustomWebsite

from src.utils import *
from src.websites import normalize_bilifix_language

__all__ = ('SettingsView',)

Expand Down Expand Up @@ -290,12 +291,14 @@ def __init__(self, setting: BaseSetting, **kwargs):

async def on_submit(self, interaction: discore.Interaction):
lang = str(self.children[0])
if len(lang) != 2:
normalizer = getattr(self.setting, 'normalize_translation_language', None)
normalized = normalizer(lang) if normalizer else (lang if len(lang) == 2 else None)
if normalized is None:
# noinspection PyUnresolvedReferences
await interaction.response.send_message(
t('settings.lang_modal.error', invalid_lang=lang, lang_iso=self.interaction_lang), ephemeral=True, delete_after=10)
return
self.setting.ctx.guild.update({'lang': lang})
self.setting.ctx.guild.update({'lang': normalized})
await self.setting.view.refresh(interaction)


Expand Down Expand Up @@ -1415,6 +1418,23 @@ class BilibiliSetting(WebsiteBaseSetting):
name = 'BiliBili'
emoji = discore.config.emoji.bilibili
proxies = {"BiliFix": "https://www.vxbilibili.com/"}
is_translation = True

def normalize_translation_language(self, language: str) -> str | None:
return normalize_bilifix_language(language)

async def translation_action(self, view: SettingsView, interaction: discore.Interaction, _) -> None:
self.translation = not self.translation
language = normalize_bilifix_language(self.ctx.guild.lang)
if language is None:
# noinspection PyUnresolvedReferences
locale = interaction.locale.value.lower()
language = normalize_bilifix_language(locale) \
or normalize_bilifix_language(locale.split('-')[0]) \
or 'en'
self.lang = language
self.ctx.guild.update({'bilibili_tr': self.translation, 'lang': self.lang})
await view.refresh(interaction)


class IFunnySetting(EmbedEZBaseSetting):
Expand Down
40 changes: 35 additions & 5 deletions src/websites.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,31 @@
from database.models.Guild import *
from src import utils

__all__ = ('WebsiteLink', 'websites')
__all__ = ('WebsiteLink', 'normalize_bilifix_language', 'websites')

_logger = logging.getLogger(__name__)

_bilifix_languages = {
'en', 'zh-tw', 'zh-cn', 'ja', 'ko', 'es', 'pt', 'fr',
'de', 'it', 'ru', 'vi', 'id', 'th', 'ms', 'tl',
}
_bilifix_language_aliases = {
'jp': 'ja', 'kr': 'ko', 'eng': 'en', 'cn': 'zh-cn',
'chs': 'zh-cn', 'zh-hans': 'zh-cn', 'tw': 'zh-tw',
'cht': 'zh-tw', 'zh-hant': 'zh-tw', 'may': 'ms',
'my': 'ms', 'vn': 'vi', 'ph': 'tl', 'fil': 'tl',
}


def normalize_bilifix_language(language: str | None) -> str | None:
"""Return a language code accepted by BiliFix."""

if not language:
return None
language = language.strip().lower()
language = _bilifix_language_aliases.get(language, language)
return language if language in _bilifix_languages else None


def call_if_valid(func: Callable) -> Callable:
"""
Expand Down Expand Up @@ -675,26 +696,35 @@ class BiliBiliLink(GenericWebsiteLink):
hypertext_label = 'BiliBili'
fix_domain = "vxbilibili.com"
fixer_name = "BiliFix"
is_translation = True
routes = generate_routes(
["bilibili.com", "b23.tv", "b22.top"],
["bilibili.com", "b23.tv"],
{
"/video/:id": None,
"/video/:id": ['p'],
"/:id": None,
"/bangumi/play/:id": None,
"/bangumi/media/:id": None,
"/bangumi/v2/media-index": ["media_id"],
"/cheese/play/:id": None,
"/opus/:id": None,
"/dynamic/:id": None,
"/read/:id": None,
"/space/:id": None,
"/detail/:id": None,
"/detail.html": ["itemsId"],
"/m/detail/:id": None,
"/manga/detail/:id": None,
})

async def get_fixed_url(self) -> tuple[str | None, str | None]:
subdomain = ""
if self.match['subdomain'] and self.match['subdomain'] not in ('www', 'm'):
if self.match['subdomain']:
subdomain = self.match['subdomain'] + '.'
fixed_url = self.get_patched_url("vx" + self.match['domain'], subdomain)
target_domain = "vx" + self.match['domain']
fixed_url = self.get_patched_url(target_domain, subdomain)
if self.guild['bilibili_tr'] and (language := normalize_bilifix_language(self.guild.lang)):
target_host = subdomain + target_domain
fixed_url = fixed_url.replace(target_host, f'{target_host}/{language}', 1)
return fixed_url, self.fixer_name


Expand Down
Loading