Joint-Teapot/joint_teapot/config.py
姚云翔523370910110 2ac29a6d89
Some checks failed
build / trigger-build-image (push) Has been cancelled
feat: support exporting Canvas group members with group info (#7)
## Summary

Add an optional `--group` argument to `export-users`.

When `--group` is not provided, the command keeps the original behavior and exports all Canvas users as:

`name,sis_id,login_id`

When `--group <group_set_prefix>` is provided, the command looks up the corresponding Canvas group set, exports only users in that group set, and appends the normalized group name as the fourth column:

`name,sis_id,login_id,group_name`

For example, if the group set is `p2team`, the exported group names will be formatted as `p2team01`, `p2team02`, `p2team10`, etc.

## Changes

- Add optional `--group` support to `export-users`
- Look up Canvas group sets by exact name first, then by prefix
- Export only members in the matched group set when `--group` is used
- Append the user's group name as the fourth CSV column
- Normalize Canvas group names like `p1team 1` and `p1team10` into `p1team01` and `p1team10`
- Sort exported rows by group number in ascending order
- Handle invalid input more gracefully:
  - if no matching group set is found, exit cleanly with an error log
  - if a Canvas group name does not follow the expected `group_set_name + number` pattern, exit cleanly with an error log

## Behavior

### Default

`joint-teapot export-users students.csv`

Output format:

`name,sis_id,login_id`

### With group export

`joint-teapot export-users p2.csv --group p2team`

Output format:

`name,sis_id,login_id,p2team01`

## Notes

This change keeps the original export behavior unchanged unless `--group` is explicitly provided.

Reviewed-on: #7
Reviewed-by: 张泊明518370910136 <bomingzh@sjtu.edu.cn>
Co-authored-by: egghead_yao <egghead_yao@sjtu.edu.cn>
Co-committed-by: egghead_yao <egghead_yao@sjtu.edu.cn>
2026-06-22 18:10:04 +08:00

66 lines
1.5 KiB
Python

from functools import lru_cache
from typing import List
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""
Define the settings (config).
"""
# canvas
canvas_domain_name: str = "oc.sjtu.edu.cn"
canvas_suffix: str = "/"
canvas_access_token: str = ""
canvas_course_id: int = 0
# gitea
gitea_domain_name: str = "focs.gc.sjtu.edu.cn"
gitea_suffix: str = "/git"
gitea_access_token: str = ""
gitea_org_name: str = ""
gitea_debug: bool = False
# git
git_host: str = "ssh://git@focs.gc.sjtu.edu.cn:2222"
repos_dir: str = "./repos"
default_branch: str = "master"
# mattermost
mattermost_domain_name: str = "focs.gc.sjtu.edu.cn"
mattermost_suffix: str = "/mm"
mattermost_access_token: str = ""
mattermost_team: str = ""
mattermost_teaching_team: List[str] = [
"charlem",
]
# joj
joj_sid: str = ""
# joj3
joj3_lock_file_path: str = ".git/teapot-joj3-all-env.lock"
joj3_lock_file_timeout: int = 30
# moss
moss_user_id: int = 9876543210
# log file
log_file_path: str = "joint-teapot.log"
stderr_log_level: str = "INFO"
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
@lru_cache()
def get_settings() -> Settings:
return Settings()
def set_settings(new_settings: Settings) -> None:
for field, value in new_settings.model_dump(exclude_unset=True).items():
setattr(settings, field, value)
settings: Settings = get_settings()