Skip to content

Commit f7856dc

Browse files
committed
🚧 Refactoring of the GogsService & adaptation on new features.
- extraction of all GogsApi code into an adapter subclass - removal of custom features to use the RepositoryServices equivalents Fixes: #18 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
1 parent 4b0ec7f commit f7856dc

File tree

2 files changed

+90
-88
lines changed

2 files changed

+90
-88
lines changed

git_repo/services/ext/gogs.py

+89-87
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,94 @@
66
from ..service import register_target, RepositoryService, os
77
from ...exceptions import ResourceError, ResourceExistsError, ResourceNotFoundError
88

9-
import gogs_client
10-
import requests
9+
from gogs_client import GogsApi, GogsRepo, Token, UsernamePassword, ApiFailure
10+
from requests import Session, HTTPError
1111
from urllib.parse import urlparse, urlunparse
1212
import functools
1313

1414
from git import config as git_config
1515
from git.exc import GitCommandError
1616

17+
class GogsClient(GogsApi):
18+
def __init__(self, *args, **kwarg):
19+
self.session = Session()
20+
super().__init__(*args, session=self.session, **kwarg)
21+
22+
def set_token(self, token):
23+
self.auth = Token(token)
24+
25+
def set_default_private(self, p):
26+
self.default_private = p
27+
28+
def setup_session(self, ssl_config, proxy=dict()):
29+
self.session.verify = ssl_config
30+
self.session.proxies.update(proxy)
31+
32+
@property
33+
def username(self):
34+
if not hasattr(self, '_username'):
35+
self._username = self.authenticated_user(self.auth).username
36+
return self._username
37+
38+
def orgs(self):
39+
orgs = self._check_ok(self._get('/user/orgs', auth=self.auth)).json()
40+
#return [gogs_client.GogsUser.from_json(org) for org in orgs]
41+
return [org['username'] for org in orgs]
42+
43+
def create_repository(self, user, repo):
44+
if user == self.username:
45+
repository = self.create_repo(self.auth, name=repo, private=self.default_private)
46+
elif user in self.orgs():
47+
data = dict(name=repo, private=self.default_private)
48+
response = self._post('/org/{}/repos'.format(user), auth=self.auth, data=data)
49+
repository = GogsRepo.from_json(self._check_ok(response).json())
50+
else:
51+
data = dict(name=repo, private=self.default_private)
52+
response = self._post('/admin/users/{}/repos'.format(user), auth=self.auth, data=data)
53+
repository = GogsRepo.from_json(self._check_ok(response).json())
54+
55+
def delete_repository(self, user, repo):
56+
return self.delete_repo(self.auth, user, repo)
57+
58+
def repository(self, user, repo):
59+
return self.get_repo(self.auth, user, repo)
60+
61+
def repositories(self, user):
62+
r = self._get('/user/repos', auth=self.auth)
63+
repositories = self._check_ok(r).json()
64+
repositories = [repo for repo in repositories if repo['owner']['username'] == user]
65+
return repositories
66+
1767
@register_target('gg', 'gogs')
1868
class GogsService(RepositoryService):
1969
fqdn = 'try.gogs.io'
20-
#fqdn = 'http://127.0.0.1:3000'
21-
gg = None
2270

2371
def __init__(self, *args, **kwargs):
24-
self.session = requests.Session()
25-
RepositoryService.__init__(self, *args, **kwargs)
26-
self.ensure_init()
27-
28-
def ensure_init(self):
29-
if self.gg is not None:
30-
return
3172
self.url_base, self.fqdn = self._url_parse(self.fqdn)
32-
if 'insecure' not in self.config:
33-
self.insecure = self.fqdn != 'try.gogs.io'
34-
self.session.verify = not self.insecure
35-
if 'server-cert' in self.config:
36-
self.session.verify = self.config['server-cert']
37-
self.default_private = self.config.get('default-private', 'false').lower() not in ('0','no','false')
38-
self.ssh_url = self.config.get('ssh-url', None) or self.fqdn
39-
if not self.repository:
40-
config = git_config.GitConfigParser(os.path.join(os.environ['HOME'], '.gitconfig'), True)
41-
else:
42-
config = self.repository.config_reader()
43-
proxies = {}
44-
for scheme in 'http https'.split():
45-
proxy = config.get_value(scheme, 'proxy', '')
46-
if proxy:
47-
proxies[scheme] = proxy
48-
self.session.proxies.update(proxies)
49-
self.gg = gogs_client.GogsApi(self.url_base, self.session)
50-
#if ':' in self._privatekey:
51-
# self.auth = gogs_client.UsernamePassword(*self._privatekey.split(':',1))
52-
#else:
53-
self.auth = gogs_client.Token(self._privatekey)
73+
self.gg = GogsClient(self.url_base)
74+
75+
super().__init__(*args, **kwargs)
76+
77+
self.gg.set_token(self._privatekey)
78+
self.gg.set_default_private(self.default_create_private)
79+
self.gg.setup_session(
80+
self.session_certificate or not self.session_insecure,
81+
self.session_proxy)
82+
83+
def connect(self):
84+
try:
85+
self.username = self.user # Call to self.gg.authenticated_user()
86+
except HTTPError as err:
87+
if err.response is not None and err.response.status_code == 401:
88+
if not self._privatekey:
89+
raise ConnectionError('Could not connect to GoGS. '
90+
'Please configure .gitconfig '
91+
'with your gogs private key.') from err
92+
else:
93+
raise ConnectionError('Could not connect to GoGS. '
94+
'Check your configuration and try again.') from err
95+
else:
96+
raise err
5497

5598
@classmethod
5699
def _url_parse(cls, url):
@@ -75,70 +118,31 @@ def url_rw(self):
75118
@classmethod
76119
def get_auth_token(cls, login, password, prompt=None):
77120
import platform
78-
name = 'git-repo2 token used on {}'.format(platform.node())
121+
name = 'git-repo token used on {}'.format(platform.node())
79122
if '/' in login:
80123
url, login = login.rsplit('/', 1)
81124
else:
82125
url = input('URL [{}]> '.format(cls.fqdn)) or cls.fqdn
83126
url_base, fqdn = cls._url_parse(url)
84-
gg = gogs_client.GogsApi(url_base)
85-
auth = gogs_client.UsernamePassword(login, password)
127+
gg = GogsApi(url_base)
128+
auth = UsernamePassword(login, password)
86129
tokens = gg.get_tokens(auth, login)
87130
tokens = dict((token.name, token.token) for token in tokens)
88131
if name in tokens:
89132
return tokens[name]
90-
if 'git-repo2 token' in tokens:
91-
return tokens['git-repo2 token']
133+
if 'git-repo token' in tokens:
134+
return tokens['git-repo token']
92135
token = gg.create_token(auth, name, login)
93136
return token.token
94137

95138
@property
96139
def user(self):
97-
return self.gg.authenticated_user(self.auth).username
98-
99-
def orgs(self):
100-
orgs = self.gg._check_ok(self.gg._get('/user/orgs', auth=self.auth)).json()
101-
#return [gogs_client.GogsUser.from_json(org) for org in orgs]
102-
return [org['username'] for org in orgs]
103-
104-
def connect(self):
105-
self.ensure_init()
106-
try:
107-
if self.insecure:
108-
try:
109-
try:
110-
urllib3 = requests.packages.urllib3
111-
except Exception:
112-
import urllib3
113-
urllib3.disable_warnings()
114-
except ImportError:
115-
pass
116-
self.username = self.user # Call to self.gg.authenticated_user()
117-
except requests.HTTPError as err:
118-
if err.response is not None and err.response.status_code == 401:
119-
if not self._privatekey:
120-
raise ConnectionError('Could not connect to GoGS. '
121-
'Please configure .gitconfig '
122-
'with your gogs private key.') from err
123-
else:
124-
raise ConnectionError('Could not connect to GoGS. '
125-
'Check your configuration and try again.') from err
126-
else:
127-
raise err
140+
return self.gg.username
128141

129142
def create(self, user, repo, add=False):
130143
try:
131-
if user == self.username:
132-
repository = self.gg.create_repo(self.auth, name=repo, private=self.default_private)
133-
elif user in self.orgs():
134-
data = dict(name=repo, private=self.default_private)
135-
response = self.gg._post('/org/{}/repos'.format(user), auth=self.auth, data=data)
136-
repository = gogs_client.GogsRepo.from_json(self.gg._check_ok(response).json())
137-
else:
138-
data = dict(name=repo, private=self.default_private)
139-
response = self.gg._post('/admin/users/{}/repos'.format(user), auth=self.auth, data=data)
140-
repository = gogs_client.GogsRepo.from_json(self.gg._check_ok(response).json())
141-
except gogs_client.ApiFailure as err:
144+
self.gg.create_repository(user, repo)
145+
except ApiFailure as err:
142146
if err.status_code == 422:
143147
raise ResourceExistsError("Project already exists.") from err
144148
else:
@@ -155,8 +159,8 @@ def delete(self, repo, user=None):
155159
if not user:
156160
user = self.username
157161
try:
158-
self.gg.delete_repo(self.auth, user, repo)
159-
except gogs_client.ApiFailure as err:
162+
self.gg.delete_repository(user, repo)
163+
except ApiFailure as err:
160164
if err.status_code == 404:
161165
raise ResourceNotFoundError("Cannot delete: repository {}/{} does not exists.".format(user, repo)) from err
162166
elif err.status_code == 403:
@@ -190,9 +194,7 @@ def col_print(lines, indent=0, pad=2):
190194
for row in rows:
191195
print(" "*indent + (" "*pad).join(line.ljust(col_width) for line in row))
192196

193-
r = self.gg._get('/user/repos', auth=self.auth)
194-
repositories = self.gg._check_ok(r).json()
195-
repositories = [repo for repo in repositories if repo['owner']['username'] == user]
197+
repositories = self.gg.repositories(user)
196198
if user != self.username and not repositories and user not in self.orgs:
197199
raise ResourceNotFoundError("Unable to list namespace {} - only authenticated user and orgs available for listing.".format(user))
198200
if not _long:
@@ -227,8 +229,8 @@ def col_print(lines, indent=0, pad=2):
227229

228230
def get_repository(self, user, repo):
229231
try:
230-
return self.gg.get_repo(self.auth, user, repo)
231-
except gogs_client.ApiFailure as err:
232+
return self.gg.repository(user, repo)
233+
except ApiFailure as err:
232234
if err.status_code == 404:
233235
raise ResourceNotFoundError("Cannot get: repository {}/{} does not exists.".format(user, repo)) from err
234236
raise ResourceError("Unhandled error: {}".format(err)) from err

tests/integration/test_gogs.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def get_service(self):
3434
# return gogs.GogsService(c=dict(fqdn=self.fqdn,__name__='gitrepo "gogs"',token=os.environ['PRIVATE_KEY_GOGS']))
3535

3636
def get_requests_session(self):
37-
return self.service.session
37+
return self.service.gg.session
3838

3939
def test_00_fork(self):
4040
pass

0 commit comments

Comments
 (0)