From a674f98e14a0120b2fd4ffb6594b4bbbc65c262a Mon Sep 17 00:00:00 2001 From: adk23333 <2633103794@qq.com> Date: Mon, 18 Dec 2023 20:20:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0pydantic=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + gitea_model.py | 350 +++++++++++++++++++++++++++++++++++++++++++++++++ server.py | 6 +- 3 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 gitea_model.py diff --git a/.gitignore b/.gitignore index 8018d9f..593967d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /config.toml +/temp.json diff --git a/gitea_model.py b/gitea_model.py new file mode 100644 index 0000000..b37681a --- /dev/null +++ b/gitea_model.py @@ -0,0 +1,350 @@ +from dataclasses import dataclass +from datetime import datetime +from enum import Enum +from typing import Optional, List, Dict + +from pydantic import BaseModel + + +class User(BaseModel): + """User,User represents a user""" + """Is user active""" + active: Optional[bool] = None + """URL to the user's avatar""" + avatar_url: Optional[str] = None + created: Optional[datetime] = None + """the user's description""" + description: Optional[str] = None + email: Optional[str] = None + """user counts""" + followers_count: Optional[int] = None + following_count: Optional[int] = None + """the user's full name""" + full_name: Optional[str] = None + """the user's id""" + id: Optional[int] = None + """Is the user an administrator""" + is_admin: Optional[bool] = None + """User locale""" + language: Optional[str] = None + last_login: Optional[datetime] = None + """the user's location""" + location: Optional[str] = None + """the user's username""" + login: Optional[str] = None + """the user's authentication sign-in name.""" + login_name: Optional[str] = None + """Is user login prohibited""" + prohibit_login: Optional[bool] = None + """Is user restricted""" + restricted: Optional[bool] = None + starred_repos_count: Optional[int] = None + """User visibility level option: public, limited, private""" + visibility: Optional[str] = None + """the user's website""" + website: Optional[str] = None + + +class Attachment(BaseModel): + """Attachment,Attachment a generic attachment""" + browser_download_url: Optional[str] = None + created_at: Optional[datetime] = None + download_count: Optional[int] = None + id: Optional[int] = None + name: Optional[str] = None + size: Optional[int] = None + uuid: Optional[str] = None + + +class Label(BaseModel): + """Label,Label a label to an issue or a pr""" + color: Optional[str] = None + description: Optional[str] = None + exclusive: Optional[bool] = None + id: Optional[int] = None + name: Optional[str] = None + url: Optional[str] = None + + +class Milestone(BaseModel): + """Milestone,Milestone milestone is a collection of issues on one repository""" + closed_at: Optional[datetime] = None + closed_issues: Optional[int] = None + created_at: Optional[datetime] = None + description: Optional[str] = None + due_on: Optional[datetime] = None + id: Optional[int] = None + open_issues: Optional[int] = None + state: Optional[str] = None + title: Optional[str] = None + updated_at: Optional[datetime] = None + + +class ExternalTracker(BaseModel): + """ExternalTracker,ExternalTracker represents settings for external tracker""" + """External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for + the username, repository name and issue index. + """ + external_tracker_format: Optional[str] = None + """External Issue Tracker issue regular expression""" + external_tracker_regexp_pattern: Optional[str] = None + """External Issue Tracker Number Format, either `numeric`, `alphanumeric`, or `regexp`""" + external_tracker_style: Optional[str] = None + """URL of external issue tracker.""" + external_tracker_url: Optional[str] = None + + +class ExternalWiki(BaseModel): + """ExternalWiki,ExternalWiki represents setting for external wiki""" + """URL of external wiki.""" + external_wiki_url: Optional[str] = None + + +class InternalTracker(BaseModel): + """InternalTracker,InternalTracker represents settings for internal tracker""" + """Let only contributors track time (Built-in issue tracker)""" + allow_only_contributors_to_track_time: Optional[bool] = None + """Enable dependencies for issues and pull requests (Built-in issue tracker)""" + enable_issue_dependencies: Optional[bool] = None + """Enable time tracking (Built-in issue tracker)""" + enable_time_tracker: Optional[bool] = None + + +class Permission(BaseModel): + """Permission,Permission represents a set of permissions""" + admin: Optional[bool] = None + pull: Optional[bool] = None + push: Optional[bool] = None + + +class Organization(BaseModel): + """Organization,Organization represents an organization""" + avatar_url: Optional[str] = None + description: Optional[str] = None + full_name: Optional[str] = None + id: Optional[int] = None + location: Optional[str] = None + name: Optional[str] = None + repo_admin_change_team_access: Optional[bool] = None + """deprecated""" + username: Optional[str] = None + visibility: Optional[str] = None + website: Optional[str] = None + + +@dataclass +class PermissionEnum(Enum): + ADMIN = "admin" + NONE = "none" + OWNER = "owner" + READ = "read" + WRITE = "write" + + +class Team(BaseModel): + """Team,Team represents a team in an organization""" + can_create_org_repo: Optional[bool] = None + description: Optional[str] = None + id: Optional[int] = None + includes_all_repositories: Optional[bool] = None + name: Optional[str] = None + organization: Optional[Organization] = None + permission: Optional[PermissionEnum] = None + units: Optional[List[str]] = None + units_map: Optional[Dict[str, str]] = None + + +class RepoTransfer(BaseModel): + """RepoTransfer,RepoTransfer represents a pending repo transfer""" + doer: Optional[User] = None + recipient: Optional[User] = None + teams: Optional[List[Team]] = None + + +class ParentClass(BaseModel): + """Repository,Repository represents a repository""" + allow_merge_commits: Optional[bool] = None + allow_rebase: Optional[bool] = None + allow_rebase_explicit: Optional[bool] = None + allow_rebase_update: Optional[bool] = None + allow_squash_merge: Optional[bool] = None + archived: Optional[bool] = None + archived_at: Optional[datetime] = None + avatar_url: Optional[str] = None + clone_url: Optional[str] = None + created_at: Optional[datetime] = None + default_allow_maintainer_edit: Optional[bool] = None + default_branch: Optional[str] = None + default_delete_branch_after_merge: Optional[bool] = None + default_merge_style: Optional[str] = None + description: Optional[str] = None + empty: Optional[bool] = None + external_tracker: Optional[ExternalTracker] = None + external_wiki: Optional[ExternalWiki] = None + fork: Optional[bool] = None + forks_count: Optional[int] = None + full_name: Optional[str] = None + has_actions: Optional[bool] = None + has_issues: Optional[bool] = None + has_packages: Optional[bool] = None + has_projects: Optional[bool] = None + has_pull_requests: Optional[bool] = None + has_releases: Optional[bool] = None + has_wiki: Optional[bool] = None + html_url: Optional[str] = None + id: Optional[int] = None + ignore_whitespace_conflicts: Optional[bool] = None + internal: Optional[bool] = None + internal_tracker: Optional[InternalTracker] = None + language: Optional[str] = None + languages_url: Optional[str] = None + link: Optional[str] = None + mirror: Optional[bool] = None + mirror_interval: Optional[str] = None + mirror_updated: Optional[datetime] = None + name: Optional[str] = None + open_issues_count: Optional[int] = None + open_pr_counter: Optional[int] = None + original_url: Optional[str] = None + owner: Optional[User] = None + parent: Optional['ParentClass'] = None + permissions: Optional[Permission] = None + private: Optional[bool] = None + release_counter: Optional[int] = None + repo_transfer: Optional[RepoTransfer] = None + size: Optional[int] = None + ssh_url: Optional[str] = None + stars_count: Optional[int] = None + template: Optional[bool] = None + updated_at: Optional[datetime] = None + url: Optional[str] = None + watchers_count: Optional[int] = None + website: Optional[str] = None + + +class PullRequestMeta(BaseModel): + """PullRequestMeta,PullRequestMeta PR info if an issue is a PR""" + merged: Optional[bool] = None + merged_at: Optional[datetime] = None + + +class RepositoryMeta(BaseModel): + """RepositoryMeta,RepositoryMeta basic repository information""" + full_name: Optional[str] = None + id: Optional[int] = None + name: Optional[str] = None + owner: Optional[str] = None + + +class Comment(BaseModel): + """Comment,Comment represents a comment on a commit or issue""" + assets: Optional[List[Attachment]] = None + body: Optional[str] = None + created_at: Optional[datetime] = None + html_url: Optional[str] = None + id: Optional[int] = None + issue_url: Optional[str] = None + original_author: Optional[str] = None + original_author_id: Optional[int] = None + pull_request_url: Optional[str] = None + updated_at: Optional[datetime] = None + user: Optional[User] = None + + +class Issue(BaseModel): + """Issue,Issue represents an issue in a repository""" + assets: Optional[List[Attachment]] = None + assignee: Optional[User] = None + assignees: Optional[List[User]] = None + body: Optional[str] = None + closed_at: Optional[datetime] = None + comments: Optional[int] = None + created_at: Optional[datetime] = None + due_date: Optional[datetime] = None + html_url: Optional[str] = None + id: Optional[int] = None + is_locked: Optional[bool] = None + labels: Optional[List[Label]] = None + milestone: Optional[Milestone] = None + number: Optional[int] = None + original_author: Optional[str] = None + original_author_id: Optional[int] = None + pin_order: Optional[int] = None + pull_request: Optional[PullRequestMeta] = None + ref: Optional[str] = None + repository: Optional[RepositoryMeta] = None + state: Optional[str] = None + title: Optional[str] = None + updated_at: Optional[datetime] = None + url: Optional[str] = None + user: Optional[User] = None + + +class Repository(BaseModel): + """Repository,Repository represents a repository""" + allow_merge_commits: Optional[bool] = None + allow_rebase: Optional[bool] = None + allow_rebase_explicit: Optional[bool] = None + allow_rebase_update: Optional[bool] = None + allow_squash_merge: Optional[bool] = None + archived: Optional[bool] = None + archived_at: Optional[datetime] = None + avatar_url: Optional[str] = None + clone_url: Optional[str] = None + created_at: Optional[datetime] = None + default_allow_maintainer_edit: Optional[bool] = None + default_branch: Optional[str] = None + default_delete_branch_after_merge: Optional[bool] = None + default_merge_style: Optional[str] = None + description: Optional[str] = None + empty: Optional[bool] = None + external_tracker: Optional[ExternalTracker] = None + external_wiki: Optional[ExternalWiki] = None + fork: Optional[bool] = None + forks_count: Optional[int] = None + full_name: Optional[str] = None + has_actions: Optional[bool] = None + has_issues: Optional[bool] = None + has_packages: Optional[bool] = None + has_projects: Optional[bool] = None + has_pull_requests: Optional[bool] = None + has_releases: Optional[bool] = None + has_wiki: Optional[bool] = None + html_url: Optional[str] = None + id: Optional[int] = None + ignore_whitespace_conflicts: Optional[bool] = None + internal: Optional[bool] = None + internal_tracker: Optional[InternalTracker] = None + language: Optional[str] = None + languages_url: Optional[str] = None + link: Optional[str] = None + mirror: Optional[bool] = None + mirror_interval: Optional[str] = None + mirror_updated: Optional[datetime] = None + name: Optional[str] = None + open_issues_count: Optional[int] = None + open_pr_counter: Optional[int] = None + original_url: Optional[str] = None + owner: Optional[User] = None + parent: Optional[ParentClass] = None + permissions: Optional[Permission] = None + private: Optional[bool] = None + release_counter: Optional[int] = None + repo_transfer: Optional[RepoTransfer] = None + size: Optional[int] = None + ssh_url: Optional[str] = None + stars_count: Optional[int] = None + template: Optional[bool] = None + updated_at: Optional[datetime] = None + url: Optional[str] = None + watchers_count: Optional[int] = None + website: Optional[str] = None + + +class WebHook(BaseModel): + action: str + issue: Issue + comment: Comment + repository: Repository + sender: User + is_pull: bool diff --git a/server.py b/server.py index 477fec5..78f58d9 100644 --- a/server.py +++ b/server.py @@ -7,6 +7,7 @@ from sanic.log import logger, Colors from sanic.response import json from socketio import AsyncClient +from gitea_model import WebHook from model import Ctx, SioConfig, Message app = Sanic('GiteaPush', ctx=Ctx) @@ -30,9 +31,8 @@ async def setup_before_start(_app): @app.post('/receive') async def receive(rqt: Request): - data = rqt.json - ctx = data['issue']['body'] - message = Message(content=f'webhook test: {ctx}', room_id=-777186831) + data = WebHook(**rqt.json) + message = Message(content=f'webhook test: {data.issue.body}', room_id=-777186831) await app.ctx.sio.emit('sendMessage', message.to_json()) return json({})