kopia lustrzana https://github.com/Langenfeld/py-gitea
Merge pull request #13 from etienne-monier/additional-options
Additional options and methodspull/15/head
commit
fe120be112
|
@ -1,6 +1,39 @@
|
||||||
*.pyc
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# dotenv
|
||||||
|
.env
|
||||||
|
|
||||||
|
# virtualenv
|
||||||
|
.venv
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
# IDE settings
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
.*.sw*
|
.*.sw*
|
||||||
*.token
|
*.token
|
||||||
|
|
||||||
# local virtual environment
|
|
||||||
.venv
|
|
||||||
|
|
|
@ -48,6 +48,45 @@ class Organization(ApiObject):
|
||||||
)
|
)
|
||||||
self.dirty_fields = {}
|
self.dirty_fields = {}
|
||||||
|
|
||||||
|
def create_repo(
|
||||||
|
self,
|
||||||
|
repoName: str,
|
||||||
|
description: str = "",
|
||||||
|
private: bool = False,
|
||||||
|
autoInit=True,
|
||||||
|
gitignores: str = None,
|
||||||
|
license: str = None,
|
||||||
|
readme: str = "Default",
|
||||||
|
issue_labels: str = None,
|
||||||
|
default_branch="master",
|
||||||
|
):
|
||||||
|
"""Create an organization Repository
|
||||||
|
|
||||||
|
Throws:
|
||||||
|
AlreadyExistsException: If the Repository exists already.
|
||||||
|
Exception: If something else went wrong.
|
||||||
|
"""
|
||||||
|
result = self.gitea.requests_post(
|
||||||
|
f"/orgs/{self.name}/repos",
|
||||||
|
data={
|
||||||
|
"name": repoName,
|
||||||
|
"description": description,
|
||||||
|
"private": private,
|
||||||
|
"auto_init": autoInit,
|
||||||
|
"gitignores": gitignores,
|
||||||
|
"license": license,
|
||||||
|
"issue_labels": issue_labels,
|
||||||
|
"readme": readme,
|
||||||
|
"default_branch": default_branch,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if "id" in result:
|
||||||
|
self.gitea.logger.info("Successfully created Repository %s " % result["name"])
|
||||||
|
else:
|
||||||
|
self.gitea.logger.error(result["message"])
|
||||||
|
raise Exception("Repository not created... (gitea: %s)" % result["message"])
|
||||||
|
return Repository.parse_response(self, result)
|
||||||
|
|
||||||
def get_repositories(self) -> List["Repository"]:
|
def get_repositories(self) -> List["Repository"]:
|
||||||
results = self.gitea.requests_get_paginated(
|
results = self.gitea.requests_get_paginated(
|
||||||
Organization.ORG_REPOS_REQUEST % self.username
|
Organization.ORG_REPOS_REQUEST % self.username
|
||||||
|
@ -175,6 +214,45 @@ class User(ApiObject):
|
||||||
self.gitea.requests_patch(User.ADMIN_EDIT_USER.format(**args), data=values)
|
self.gitea.requests_patch(User.ADMIN_EDIT_USER.format(**args), data=values)
|
||||||
self.dirty_fields = {}
|
self.dirty_fields = {}
|
||||||
|
|
||||||
|
def create_repo(
|
||||||
|
self,
|
||||||
|
repoName: str,
|
||||||
|
description: str = "",
|
||||||
|
private: bool = False,
|
||||||
|
autoInit=True,
|
||||||
|
gitignores: str = None,
|
||||||
|
license: str = None,
|
||||||
|
readme: str = "Default",
|
||||||
|
issue_labels: str = None,
|
||||||
|
default_branch="master",
|
||||||
|
):
|
||||||
|
"""Create a user Repository
|
||||||
|
|
||||||
|
Throws:
|
||||||
|
AlreadyExistsException: If the Repository exists already.
|
||||||
|
Exception: If something else went wrong.
|
||||||
|
"""
|
||||||
|
result = self.gitea.requests_post(
|
||||||
|
"/user/repos",
|
||||||
|
data={
|
||||||
|
"name": repoName,
|
||||||
|
"description": description,
|
||||||
|
"private": private,
|
||||||
|
"auto_init": autoInit,
|
||||||
|
"gitignores": gitignores,
|
||||||
|
"license": license,
|
||||||
|
"issue_labels": issue_labels,
|
||||||
|
"readme": readme,
|
||||||
|
"default_branch": default_branch,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if "id" in result:
|
||||||
|
self.gitea.logger.info("Successfully created Repository %s " % result["name"])
|
||||||
|
else:
|
||||||
|
self.gitea.logger.error(result["message"])
|
||||||
|
raise Exception("Repository not created... (gitea: %s)" % result["message"])
|
||||||
|
return Repository.parse_response(self, result)
|
||||||
|
|
||||||
def get_repositories(self) -> List["Repository"]:
|
def get_repositories(self) -> List["Repository"]:
|
||||||
""" Get all Repositories owned by this User."""
|
""" Get all Repositories owned by this User."""
|
||||||
url = f"/users/{self.username}/repos"
|
url = f"/users/{self.username}/repos"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
|
import json
|
||||||
from typing import List, Dict, Union
|
from typing import List, Dict, Union
|
||||||
|
|
||||||
import requests
|
|
||||||
from frozendict import frozendict
|
from frozendict import frozendict
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
|
||||||
from .apiobject import User, Organization, Repository, Team
|
from .apiobject import User, Organization, Repository, Team
|
||||||
from .exceptions import NotFoundException, ConflictException, AlreadyExistsException
|
from .exceptions import NotFoundException, ConflictException, AlreadyExistsException
|
||||||
|
@ -19,17 +20,47 @@ class Gitea:
|
||||||
CREATE_ORG = """/admin/users/%s/orgs""" # <username>
|
CREATE_ORG = """/admin/users/%s/orgs""" # <username>
|
||||||
CREATE_TEAM = """/orgs/%s/teams""" # <orgname>
|
CREATE_TEAM = """/orgs/%s/teams""" # <orgname>
|
||||||
|
|
||||||
def __init__(self, gitea_url: str, token_text: str, log_level="INFO"):
|
def __init__(
|
||||||
""" Initializing Gitea-instance."""
|
self,
|
||||||
|
gitea_url: str,
|
||||||
|
token_text=None,
|
||||||
|
auth=None,
|
||||||
|
verify=True,
|
||||||
|
log_level="INFO"
|
||||||
|
):
|
||||||
|
""" Initializing Gitea-instance
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gitea_url (str): The Gitea instance URL.
|
||||||
|
token_text (str, None): The access token, by default None.
|
||||||
|
auth (tuple, None): The user credentials
|
||||||
|
`(username, password)`, by default None.
|
||||||
|
verify (bool): If True, allow insecure server connections
|
||||||
|
when using SSL.
|
||||||
|
log_level (str): The log level, by default `INFO`.
|
||||||
|
"""
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.logger.setLevel(log_level)
|
self.logger.setLevel(log_level)
|
||||||
self.headers = {
|
self.headers = {
|
||||||
"Authorization": "token " + token_text,
|
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
}
|
}
|
||||||
self.url = gitea_url
|
self.url = gitea_url
|
||||||
self.requests = requests.Session()
|
self.requests = requests.Session()
|
||||||
|
|
||||||
|
# Manage authentification
|
||||||
|
if not token_text and not auth:
|
||||||
|
raise ValueError("Please provide auth or token_text, but not both")
|
||||||
|
if token_text:
|
||||||
|
self.headers["Authorization"] = "token " + token_text
|
||||||
|
if auth:
|
||||||
|
self.requests.auth = auth
|
||||||
|
|
||||||
|
# Manage SSL certification verification
|
||||||
|
self.requests.verify = verify
|
||||||
|
if not verify:
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
|
||||||
def __get_url(self, endpoint):
|
def __get_url(self, endpoint):
|
||||||
url = self.url + "/api/v1" + endpoint
|
url = self.url + "/api/v1" + endpoint
|
||||||
self.logger.debug("Url: %s" % url)
|
self.logger.debug("Url: %s" % url)
|
||||||
|
@ -148,6 +179,7 @@ class Gitea:
|
||||||
user_name: str,
|
user_name: str,
|
||||||
email: str,
|
email: str,
|
||||||
password: str,
|
password: str,
|
||||||
|
full_name: str = None,
|
||||||
login_name: str = None,
|
login_name: str = None,
|
||||||
change_pw=True,
|
change_pw=True,
|
||||||
send_notify=True,
|
send_notify=True,
|
||||||
|
@ -160,9 +192,12 @@ class Gitea:
|
||||||
"""
|
"""
|
||||||
if not login_name:
|
if not login_name:
|
||||||
login_name = user_name
|
login_name = user_name
|
||||||
|
if not full_name:
|
||||||
|
full_name = user_name
|
||||||
request_data = {
|
request_data = {
|
||||||
"source_id": source_id,
|
"source_id": source_id,
|
||||||
"login_name": login_name,
|
"login_name": login_name,
|
||||||
|
"full_name": full_name,
|
||||||
"username": user_name,
|
"username": user_name,
|
||||||
"email": email,
|
"email": email,
|
||||||
"password": password,
|
"password": password,
|
||||||
|
@ -197,12 +232,17 @@ class Gitea:
|
||||||
license: str = None,
|
license: str = None,
|
||||||
readme: str = "Default",
|
readme: str = "Default",
|
||||||
issue_labels: str = None,
|
issue_labels: str = None,
|
||||||
|
default_branch="master",
|
||||||
):
|
):
|
||||||
""" Create a Repository.
|
""" Create a Repository as the administrator
|
||||||
Throws:
|
|
||||||
AlreadyExistsException, if Repository exists already.
|
|
||||||
Exception, if something else went wrong.
|
|
||||||
|
|
||||||
|
Throws:
|
||||||
|
AlreadyExistsException: If the Repository exists already.
|
||||||
|
Exception: If something else went wrong.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Non-admin users can not use this method. Please use instead
|
||||||
|
`gitea.User.create_repo` or `gitea.Organization.create_repo`.
|
||||||
"""
|
"""
|
||||||
# although this only says user in the api, this also works for
|
# although this only says user in the api, this also works for
|
||||||
# organizations
|
# organizations
|
||||||
|
@ -218,6 +258,7 @@ class Gitea:
|
||||||
"license": license,
|
"license": license,
|
||||||
"issue_labels": issue_labels,
|
"issue_labels": issue_labels,
|
||||||
"readme": readme,
|
"readme": readme,
|
||||||
|
"default_branch": default_branch,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if "id" in result:
|
if "id" in result:
|
||||||
|
@ -267,6 +308,8 @@ class Gitea:
|
||||||
name: str,
|
name: str,
|
||||||
description: str = "",
|
description: str = "",
|
||||||
permission: str = "read",
|
permission: str = "read",
|
||||||
|
can_create_org_repo: bool = False,
|
||||||
|
includes_all_repositories: bool = False,
|
||||||
units=(
|
units=(
|
||||||
"repo.code",
|
"repo.code",
|
||||||
"repo.issues",
|
"repo.issues",
|
||||||
|
@ -291,6 +334,8 @@ class Gitea:
|
||||||
"name": name,
|
"name": name,
|
||||||
"description": description,
|
"description": description,
|
||||||
"permission": permission,
|
"permission": permission,
|
||||||
|
"can_create_org_repo": can_create_org_repo,
|
||||||
|
"includes_all_repositories": includes_all_repositories,
|
||||||
"units": units,
|
"units": units,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""Fixtures for testing py-gitea
|
||||||
|
|
||||||
|
Instructions
|
||||||
|
------------
|
||||||
|
put a ".token" file into your directory containg only the token for gitea
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from gitea import Gitea
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def instance(scope="module"):
|
||||||
|
try:
|
||||||
|
url = os.getenv("PY_GITEA_URL")
|
||||||
|
token = os.getenv("PY_GITEA_TOKEN")
|
||||||
|
auth = os.getenv("PY_GITEA_AUTH")
|
||||||
|
if not url:
|
||||||
|
raise ValueError("No Gitea URL was provided")
|
||||||
|
if token and auth:
|
||||||
|
raise ValueError("Please provide auth or token_text, but not both")
|
||||||
|
g = Gitea(url, token_text=token, auth=auth, verify=False)
|
||||||
|
print("Gitea Version: " + g.get_version())
|
||||||
|
print("API-Token belongs to user: " + g.get_user().username)
|
||||||
|
return g
|
||||||
|
except:
|
||||||
|
assert (
|
||||||
|
False
|
||||||
|
), "Gitea could not load. \
|
||||||
|
- Instance running at http://localhost:3000 \
|
||||||
|
- Token at .token \
|
||||||
|
?"
|
Ładowanie…
Reference in New Issue