Skip to content

Commit

Permalink
完成自動更新功能
Browse files Browse the repository at this point in the history
1. 完成Github Actions每週自動更新黑名單
2. 新增登入檢查功能
3. 更新套件依賴
  • Loading branch information
ZhenShuo2021 committed Dec 26, 2024
1 parent d478929 commit d245bca
Show file tree
Hide file tree
Showing 9 changed files with 806 additions and 134 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/update-blacklist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: update-blacklist

on:
schedule:
- cron: '0 4 * * 0'
workflow_dispatch:

jobs:
update-blacklist:
runs-on: ubuntu-latest
environment: update-blacklist
permissions:
contents: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: uv.lock
python-version: 3.13

- name: Run Python script
env:
COOKIES_BASE64: ${{ secrets.COOKIES_BASE64 }}
BAHA_USERNAME: ${{ secrets.BAHA_USERNAME }}
run: uv run -m baha_blacklist.actions

- name: Commit and push changes
run: |
if [[ -n "$(git status --porcelain)" ]]; then
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
git ls-files | grep -i 'cookie' | xargs git reset # 排除 cookie
git commit -m "automated update blacklist" --no-verify
git push
else
echo "No changes to commit"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repos:
- id: pyupgrade

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.4
rev: v0.8.4
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down
4 changes: 3 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
"type": "debugpy",
"request": "launch",
"justMyCode": false,
"program": "main.py",
"program": "run.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"args": [
// "--username",
// "--mode",
// "export",
]
}
]
Expand Down
54 changes: 54 additions & 0 deletions baha_blacklist/actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# DO NOT IMPORT THIS FILE FROM OTHER FILE
import os
import sys

from .constant import BLACKLIST_DEST
from .main import GamerAPIExtended
from .utils import base64_decode, base64_encode, write_users

cookie_path = "decoded_cookies.txt"


def cookies_to_base64(
input_file: str = "cookies.txt",
output_file: str = "cookies_base64.txt",
write: bool = False,
) -> None | str:
"""讀取 cookies 將內容進行 Base64 編碼後寫入或印出"""
with open(input_file) as f:
cookies_content = f.read()
cookies_base64 = base64_encode(cookies_content)
if write:
with open(output_file, "w") as f:
f.write(cookies_base64)
else:
return cookies_base64


def decode_cookies_from_base64():
"""從 GitHub 環境變數獲取 Base64 編碼的 cookie, 解碼並寫進臨時檔案"""
cookies_base64 = os.getenv("COOKIES_BASE64")
if not cookies_base64:
raise ValueError("環境變數 COOKIES_BASE64 未設定或為空")

cookies_content = base64_decode(cookies_base64)

with open(cookie_path, "w") as f:
f.write(cookies_content)


if __name__ == "__main__":
cookie_jar = decode_cookies_from_base64()

username = os.environ["BAHA_USERNAME"]
api = GamerAPIExtended(username, cookie_path)

if not api.check_login():
print("登入失敗,請更新 Cookies")
sys.exit(0)

print("開始匯出黑名單...")
existing_users = api.export_users(username)
print(f"黑名單匯出成功, 總共匯出 {len(existing_users)} 個名單")
write_users(BLACKLIST_DEST, existing_users)
print("黑名單匯出結束\n")
22 changes: 14 additions & 8 deletions baha_blacklist/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
import time
import random
import http.cookiejar as cookiejar
Expand Down Expand Up @@ -43,10 +44,7 @@ def __init__(self, username: str, cookie_path: str) -> None:
})
self.base_url = "https://home.gamer.com.tw/"
self.api_url = "https://api.gamer.com.tw/user/v1/friend_add.php"
self.headers = {
"User-Agent": USER_AGENT,
"Referer": "https://www.gamer.com.tw/",
}
self.headers = {"User-Agent": USER_AGENT, "Referer": "https://www.gamer.com.tw/"}
self.csrf_token = None

def add_user(self, uid: str, category="bad") -> str | None:
Expand Down Expand Up @@ -139,6 +137,12 @@ def export_users(self, username: str, type_id=5) -> list[str]:
print(f"擷取黑名單列表失敗: {e}")
return []

def check_login(self) -> bool:
"""檢查是否成功登入, 被 redirect 代表登入失敗, 回傳 False"""
url = "https://home.gamer.com.tw/setting/"
response = self.session.get(url, headers=self.headers)
return not response.history or not (300 <= response.history[0].status_code < 400)

def _update_csrf(self) -> None:
response = self.session.get(self.base_url, headers=self.headers)
if response.status_code != 200:
Expand All @@ -154,10 +158,8 @@ class GamerAPIExtended(GamerAPI):

def __init__(self, username, cookie_path: str) -> None:
super().__init__(username, cookie_path)
self.user_info_time = "上站次數"
self.user_info_login = "上站日期"
self.user_info_time = to_unicode(self.user_info_time)
self.user_info_login = to_unicode(self.user_info_login)
self.user_info_time = to_unicode("上站次數")
self.user_info_login = to_unicode("上站日期")

def remove_user(self, uid: str) -> str:
"""發送 POST 請求刪除用戶 (移除黑名單)"""
Expand Down Expand Up @@ -341,6 +343,10 @@ def main(args) -> None:
username = args.username
api = GamerAPIExtended(username, cookie_path)

if not api.check_login():
print("登入失敗,請更新 Cookies")
sys.exit(0)

if "export" in args.mode:
print("開始匯出黑名單...")
existing_users = api.export_users(username)
Expand Down
11 changes: 11 additions & 0 deletions baha_blacklist/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import base64
import argparse
from datetime import datetime
from typing import Literal
Expand Down Expand Up @@ -38,6 +39,16 @@ def get_default_user_info() -> tuple[Literal[51], datetime]:
return visit_count, login_date


def base64_encode(data: str) -> str:
"""編碼成base64格式"""
return base64.b64encode(data.encode("utf-8")).decode("utf-8")


def base64_decode(encoded_data: str) -> str:
"""解碼回字串"""
return base64.b64decode(encoded_data.encode("utf-8")).decode("utf-8")


class CustomHelpFormatter(argparse.RawTextHelpFormatter):
def __init__(self, prog) -> None:
super().__init__(prog, max_help_position=36)
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ dev-dependencies = [
"mypy >= 1.13.0",
"pre-commit >= 4.0.0",
"isort >= 5.13.2",
"ipykernel>=6.29.5",
"pyperclip>=1.9.0",
]

[tool.ruff]
Expand Down
7 changes: 7 additions & 0 deletions run_enc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Github Action 用,獲取 base64 編碼的 cookies
import pyperclip

from baha_blacklist.actions import cookies_to_base64

pyperclip.copy(cookies_to_base64())
print("Base64 編碼的 Cookies 已複製到剪貼簿")
Loading

0 comments on commit d245bca

Please sign in to comment.