Skip to content

Commit 7fd3226

Browse files
Merge pull request #996 from python-gitlab/feat/appearance
feat: add appearance API
2 parents afdc43f + 4c4ac5c commit 7fd3226

File tree

5 files changed

+193
-0
lines changed

5 files changed

+193
-0
lines changed

docs/api-objects.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ API examples
66
:maxdepth: 1
77

88
gl_objects/access_requests
9+
gl_objects/appearance
910
gl_objects/emojis
1011
gl_objects/badges
1112
gl_objects/branches

docs/gl_objects/appearance.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
##########
2+
Appearance
3+
##########
4+
5+
Reference
6+
---------
7+
8+
* v4 API:
9+
10+
+ :class:`gitlab.v4.objects.ApplicationAppearance`
11+
+ :class:`gitlab.v4.objects.ApplicationAppearanceManager`
12+
+ :attr:`gitlab.Gitlab.appearance`
13+
14+
* GitLab API: https://docs.gitlab.com/ce/api/appearance.html
15+
16+
Examples
17+
--------
18+
19+
Get the appearance::
20+
21+
appearance = gl.appearance.get()
22+
23+
Update the appearance::
24+
25+
appearance.title = "Test"
26+
appearance.save()

gitlab/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ def __init__(
129129
self.projects = objects.ProjectManager(self)
130130
self.runners = objects.RunnerManager(self)
131131
self.settings = objects.ApplicationSettingsManager(self)
132+
self.appearance = objects.ApplicationAppearanceManager(self)
132133
self.sidekiq = objects.SidekiqManager(self)
133134
self.snippets = objects.SnippetManager(self)
134135
self.users = objects.UserManager(self)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import unittest
2+
import gitlab
3+
import os
4+
import pickle
5+
import tempfile
6+
import json
7+
import unittest
8+
import requests
9+
from gitlab import * # noqa
10+
from gitlab.v4.objects import * # noqa
11+
from httmock import HTTMock, urlmatch, response # noqa
12+
13+
14+
headers = {"content-type": "application/json"}
15+
16+
17+
class TestApplicationAppearance(unittest.TestCase):
18+
def setUp(self):
19+
self.gl = Gitlab(
20+
"http://localhost",
21+
private_token="private_token",
22+
ssl_verify=True,
23+
api_version="4",
24+
)
25+
self.title = "GitLab Test Instance"
26+
self.new_title = "new-title"
27+
self.description = "gitlab-test.example.com"
28+
self.new_description = "new-description"
29+
30+
def test_get_update_appearance(self):
31+
@urlmatch(
32+
scheme="http",
33+
netloc="localhost",
34+
path="/api/v4/application/appearance",
35+
method="get",
36+
)
37+
def resp_get_appearance(url, request):
38+
content = """{
39+
"title": "%s",
40+
"description": "%s",
41+
"logo": "/uploads/-/system/appearance/logo/1/logo.png",
42+
"header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
43+
"favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
44+
"new_project_guidelines": "Please read the FAQs for help.",
45+
"header_message": "",
46+
"footer_message": "",
47+
"message_background_color": "#e75e40",
48+
"message_font_color": "#ffffff",
49+
"email_header_and_footer_enabled": false}""" % (
50+
self.title,
51+
self.description,
52+
)
53+
content = content.encode("utf-8")
54+
return response(200, content, headers, None, 25, request)
55+
56+
@urlmatch(
57+
scheme="http",
58+
netloc="localhost",
59+
path="/api/v4/application/appearance",
60+
method="put",
61+
)
62+
def resp_update_appearance(url, request):
63+
content = """{
64+
"title": "%s",
65+
"description": "%s",
66+
"logo": "/uploads/-/system/appearance/logo/1/logo.png",
67+
"header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
68+
"favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
69+
"new_project_guidelines": "Please read the FAQs for help.",
70+
"header_message": "",
71+
"footer_message": "",
72+
"message_background_color": "#e75e40",
73+
"message_font_color": "#ffffff",
74+
"email_header_and_footer_enabled": false}""" % (
75+
self.new_title,
76+
self.new_description,
77+
)
78+
content = content.encode("utf-8")
79+
return response(200, content, headers, None, 25, request)
80+
81+
with HTTMock(resp_get_appearance), HTTMock(resp_update_appearance):
82+
appearance = self.gl.appearance.get()
83+
self.assertEqual(appearance.title, self.title)
84+
self.assertEqual(appearance.description, self.description)
85+
appearance.title = self.new_title
86+
appearance.description = self.new_description
87+
appearance.save()
88+
self.assertEqual(appearance.title, self.new_title)
89+
self.assertEqual(appearance.description, self.new_description)
90+
91+
def test_update_appearance(self):
92+
@urlmatch(
93+
scheme="http",
94+
netloc="localhost",
95+
path="/api/v4/application/appearance",
96+
method="put",
97+
)
98+
def resp_update_appearance(url, request):
99+
content = """{
100+
"title": "%s",
101+
"description": "%s",
102+
"logo": "/uploads/-/system/appearance/logo/1/logo.png",
103+
"header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
104+
"favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
105+
"new_project_guidelines": "Please read the FAQs for help.",
106+
"header_message": "",
107+
"footer_message": "",
108+
"message_background_color": "#e75e40",
109+
"message_font_color": "#ffffff",
110+
"email_header_and_footer_enabled": false}""" % (
111+
self.new_title,
112+
self.new_description,
113+
)
114+
content = content.encode("utf-8")
115+
return response(200, content, headers, None, 25, request)
116+
117+
with HTTMock(resp_update_appearance):
118+
resp = self.gl.appearance.update(
119+
title=self.new_title, description=self.new_description
120+
)

gitlab/v4/objects.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,51 @@ class CurrentUserManager(GetWithoutIdMixin, RESTManager):
514514
_obj_cls = CurrentUser
515515

516516

517+
class ApplicationAppearance(SaveMixin, RESTObject):
518+
_id_attr = None
519+
520+
521+
class ApplicationAppearanceManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
522+
_path = "/application/appearance"
523+
_obj_cls = ApplicationAppearance
524+
_update_attrs = (
525+
tuple(),
526+
(
527+
"title",
528+
"description",
529+
"logo",
530+
"header_logo",
531+
"favicon",
532+
"new_project_guidelines",
533+
"header_message",
534+
"footer_message",
535+
"message_background_color",
536+
"message_font_color",
537+
"email_header_and_footer_enabled",
538+
),
539+
)
540+
541+
@exc.on_http_error(exc.GitlabUpdateError)
542+
def update(self, id=None, new_data=None, **kwargs):
543+
"""Update an object on the server.
544+
545+
Args:
546+
id: ID of the object to update (can be None if not required)
547+
new_data: the update data for the object
548+
**kwargs: Extra options to send to the server (e.g. sudo)
549+
550+
Returns:
551+
dict: The new object data (*not* a RESTObject)
552+
553+
Raises:
554+
GitlabAuthenticationError: If authentication is not correct
555+
GitlabUpdateError: If the server cannot perform the request
556+
"""
557+
new_data = new_data or {}
558+
data = new_data.copy()
559+
super(ApplicationAppearanceManager, self).update(id, data, **kwargs)
560+
561+
517562
class ApplicationSettings(SaveMixin, RESTObject):
518563
_id_attr = None
519564

0 commit comments

Comments
 (0)