##// END OF EJS Templates
release: merge back stable branch into default
milka -
r4642:cced0269 merge default
parent child
Show More
@@ -0,0 +1,46
1 |RCE| 4.24.1 |RNS|
2 ------------------
3
4 Release Date
5 ^^^^^^^^^^^^
6
7 - 2021-02-04
8
9
10 New Features
11 ^^^^^^^^^^^^
12
13
14
15 General
16 ^^^^^^^
17
18 - Core: added statsd client for statistics usage.
19 - Clone urls: allow custom clone by id template so users can set clone-by-id as default.
20 - Automation: enable check for new version for EE edition as automation task that will send notifications when new RhodeCode version is available
21
22 Security
23 ^^^^^^^^
24
25
26
27 Performance
28 ^^^^^^^^^^^
29
30 - Core: bumped git to 2.30.0
31
32
33 Fixes
34 ^^^^^
35
36 - Comments: add ability to resolve todos from the side-bar. This should prevent situations
37 when a TODO was left over in outdated/removed code pieces, and users needs to search to resolve them.
38 - Pull requests: fixed a case when template marker was used in description field causing 500 errors on commenting.
39 - Merges: fixed excessive data saved in merge metadata that could not fit inside the DB table.
40 - Exceptions: fixed problem with exceptions formatting resulting in limited exception data reporting.
41
42
43 Upgrade notes
44 ^^^^^^^^^^^^^
45
46 - Un-scheduled release addressing problems in 4.24.X releases.
@@ -0,0 +1,12
1 diff -rup pytest-4.6.5-orig/setup.py pytest-4.6.5/setup.py
2 --- pytest-4.6.5-orig/setup.py 2018-04-10 10:23:04.000000000 +0200
3 +++ pytest-4.6.5/setup.py 2018-04-10 10:23:34.000000000 +0200
4 @@ -24,7 +24,7 @@ INSTALL_REQUIRES = [
5 def main():
6 setup(
7 use_scm_version={"write_to": "src/_pytest/_version.py"},
8 - setup_requires=["setuptools-scm", "setuptools>=40.0"],
9 + setup_requires=["setuptools-scm", "setuptools<=42.0"],
10 package_dir={"": "src"},
11 # fmt: off
12 extras_require={ No newline at end of file
@@ -0,0 +1,46
1 from __future__ import absolute_import, division, unicode_literals
2
3 import logging
4
5 from .stream import TCPStatsClient, UnixSocketStatsClient # noqa
6 from .udp import StatsClient # noqa
7
8 HOST = 'localhost'
9 PORT = 8125
10 IPV6 = False
11 PREFIX = None
12 MAXUDPSIZE = 512
13
14 log = logging.getLogger('rhodecode.statsd')
15
16
17 def statsd_config(config, prefix='statsd.'):
18 _config = {}
19 for key in config.keys():
20 if key.startswith(prefix):
21 _config[key[len(prefix):]] = config[key]
22 return _config
23
24
25 def client_from_config(configuration, prefix='statsd.', **kwargs):
26 from pyramid.settings import asbool
27
28 _config = statsd_config(configuration, prefix)
29 statsd_enabled = asbool(_config.pop('enabled', False))
30 if not statsd_enabled:
31 log.debug('statsd client not enabled by statsd.enabled = flag, skipping...')
32 return
33
34 host = _config.pop('statsd_host', HOST)
35 port = _config.pop('statsd_port', PORT)
36 prefix = _config.pop('statsd_prefix', PREFIX)
37 maxudpsize = _config.pop('statsd_maxudpsize', MAXUDPSIZE)
38 ipv6 = asbool(_config.pop('statsd_ipv6', IPV6))
39 log.debug('configured statsd client %s:%s', host, port)
40
41 return StatsClient(
42 host=host, port=port, prefix=prefix, maxudpsize=maxudpsize, ipv6=ipv6)
43
44
45 def get_statsd_client(request):
46 return client_from_config(request.registry.settings)
@@ -0,0 +1,107
1 from __future__ import absolute_import, division, unicode_literals
2
3 import random
4 from collections import deque
5 from datetime import timedelta
6
7 from .timer import Timer
8
9
10 class StatsClientBase(object):
11 """A Base class for various statsd clients."""
12
13 def close(self):
14 """Used to close and clean up any underlying resources."""
15 raise NotImplementedError()
16
17 def _send(self):
18 raise NotImplementedError()
19
20 def pipeline(self):
21 raise NotImplementedError()
22
23 def timer(self, stat, rate=1):
24 return Timer(self, stat, rate)
25
26 def timing(self, stat, delta, rate=1):
27 """
28 Send new timing information.
29
30 `delta` can be either a number of milliseconds or a timedelta.
31 """
32 if isinstance(delta, timedelta):
33 # Convert timedelta to number of milliseconds.
34 delta = delta.total_seconds() * 1000.
35 self._send_stat(stat, '%0.6f|ms' % delta, rate)
36
37 def incr(self, stat, count=1, rate=1):
38 """Increment a stat by `count`."""
39 self._send_stat(stat, '%s|c' % count, rate)
40
41 def decr(self, stat, count=1, rate=1):
42 """Decrement a stat by `count`."""
43 self.incr(stat, -count, rate)
44
45 def gauge(self, stat, value, rate=1, delta=False):
46 """Set a gauge value."""
47 if value < 0 and not delta:
48 if rate < 1:
49 if random.random() > rate:
50 return
51 with self.pipeline() as pipe:
52 pipe._send_stat(stat, '0|g', 1)
53 pipe._send_stat(stat, '%s|g' % value, 1)
54 else:
55 prefix = '+' if delta and value >= 0 else ''
56 self._send_stat(stat, '%s%s|g' % (prefix, value), rate)
57
58 def set(self, stat, value, rate=1):
59 """Set a set value."""
60 self._send_stat(stat, '%s|s' % value, rate)
61
62 def _send_stat(self, stat, value, rate):
63 self._after(self._prepare(stat, value, rate))
64
65 def _prepare(self, stat, value, rate):
66 if rate < 1:
67 if random.random() > rate:
68 return
69 value = '%s|@%s' % (value, rate)
70
71 if self._prefix:
72 stat = '%s.%s' % (self._prefix, stat)
73
74 return '%s:%s' % (stat, value)
75
76 def _after(self, data):
77 if data:
78 self._send(data)
79
80
81 class PipelineBase(StatsClientBase):
82
83 def __init__(self, client):
84 self._client = client
85 self._prefix = client._prefix
86 self._stats = deque()
87
88 def _send(self):
89 raise NotImplementedError()
90
91 def _after(self, data):
92 if data is not None:
93 self._stats.append(data)
94
95 def __enter__(self):
96 return self
97
98 def __exit__(self, typ, value, tb):
99 self.send()
100
101 def send(self):
102 if not self._stats:
103 return
104 self._send()
105
106 def pipeline(self):
107 return self.__class__(self)
@@ -0,0 +1,75
1 from __future__ import absolute_import, division, unicode_literals
2
3 import socket
4
5 from .base import StatsClientBase, PipelineBase
6
7
8 class StreamPipeline(PipelineBase):
9 def _send(self):
10 self._client._after('\n'.join(self._stats))
11 self._stats.clear()
12
13
14 class StreamClientBase(StatsClientBase):
15 def connect(self):
16 raise NotImplementedError()
17
18 def close(self):
19 if self._sock and hasattr(self._sock, 'close'):
20 self._sock.close()
21 self._sock = None
22
23 def reconnect(self):
24 self.close()
25 self.connect()
26
27 def pipeline(self):
28 return StreamPipeline(self)
29
30 def _send(self, data):
31 """Send data to statsd."""
32 if not self._sock:
33 self.connect()
34 self._do_send(data)
35
36 def _do_send(self, data):
37 self._sock.sendall(data.encode('ascii') + b'\n')
38
39
40 class TCPStatsClient(StreamClientBase):
41 """TCP version of StatsClient."""
42
43 def __init__(self, host='localhost', port=8125, prefix=None,
44 timeout=None, ipv6=False):
45 """Create a new client."""
46 self._host = host
47 self._port = port
48 self._ipv6 = ipv6
49 self._timeout = timeout
50 self._prefix = prefix
51 self._sock = None
52
53 def connect(self):
54 fam = socket.AF_INET6 if self._ipv6 else socket.AF_INET
55 family, _, _, _, addr = socket.getaddrinfo(
56 self._host, self._port, fam, socket.SOCK_STREAM)[0]
57 self._sock = socket.socket(family, socket.SOCK_STREAM)
58 self._sock.settimeout(self._timeout)
59 self._sock.connect(addr)
60
61
62 class UnixSocketStatsClient(StreamClientBase):
63 """Unix domain socket version of StatsClient."""
64
65 def __init__(self, socket_path, prefix=None, timeout=None):
66 """Create a new client."""
67 self._socket_path = socket_path
68 self._timeout = timeout
69 self._prefix = prefix
70 self._sock = None
71
72 def connect(self):
73 self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
74 self._sock.settimeout(self._timeout)
75 self._sock.connect(self._socket_path)
@@ -0,0 +1,71
1 from __future__ import absolute_import, division, unicode_literals
2
3 import functools
4
5 # Use timer that's not susceptible to time of day adjustments.
6 try:
7 # perf_counter is only present on Py3.3+
8 from time import perf_counter as time_now
9 except ImportError:
10 # fall back to using time
11 from time import time as time_now
12
13
14 def safe_wraps(wrapper, *args, **kwargs):
15 """Safely wraps partial functions."""
16 while isinstance(wrapper, functools.partial):
17 wrapper = wrapper.func
18 return functools.wraps(wrapper, *args, **kwargs)
19
20
21 class Timer(object):
22 """A context manager/decorator for statsd.timing()."""
23
24 def __init__(self, client, stat, rate=1):
25 self.client = client
26 self.stat = stat
27 self.rate = rate
28 self.ms = None
29 self._sent = False
30 self._start_time = None
31
32 def __call__(self, f):
33 """Thread-safe timing function decorator."""
34 @safe_wraps(f)
35 def _wrapped(*args, **kwargs):
36 start_time = time_now()
37 try:
38 return f(*args, **kwargs)
39 finally:
40 elapsed_time_ms = 1000.0 * (time_now() - start_time)
41 self.client.timing(self.stat, elapsed_time_ms, self.rate)
42 return _wrapped
43
44 def __enter__(self):
45 return self.start()
46
47 def __exit__(self, typ, value, tb):
48 self.stop()
49
50 def start(self):
51 self.ms = None
52 self._sent = False
53 self._start_time = time_now()
54 return self
55
56 def stop(self, send=True):
57 if self._start_time is None:
58 raise RuntimeError('Timer has not started.')
59 dt = time_now() - self._start_time
60 self.ms = 1000.0 * dt # Convert to milliseconds.
61 if send:
62 self.send()
63 return self
64
65 def send(self):
66 if self.ms is None:
67 raise RuntimeError('No data recorded.')
68 if self._sent:
69 raise RuntimeError('Already sent data.')
70 self._sent = True
71 self.client.timing(self.stat, self.ms, self.rate)
@@ -0,0 +1,55
1 from __future__ import absolute_import, division, unicode_literals
2
3 import socket
4
5 from .base import StatsClientBase, PipelineBase
6
7
8 class Pipeline(PipelineBase):
9
10 def __init__(self, client):
11 super(Pipeline, self).__init__(client)
12 self._maxudpsize = client._maxudpsize
13
14 def _send(self):
15 data = self._stats.popleft()
16 while self._stats:
17 # Use popleft to preserve the order of the stats.
18 stat = self._stats.popleft()
19 if len(stat) + len(data) + 1 >= self._maxudpsize:
20 self._client._after(data)
21 data = stat
22 else:
23 data += '\n' + stat
24 self._client._after(data)
25
26
27 class StatsClient(StatsClientBase):
28 """A client for statsd."""
29
30 def __init__(self, host='localhost', port=8125, prefix=None,
31 maxudpsize=512, ipv6=False):
32 """Create a new client."""
33 fam = socket.AF_INET6 if ipv6 else socket.AF_INET
34 family, _, _, _, addr = socket.getaddrinfo(
35 host, port, fam, socket.SOCK_DGRAM)[0]
36 self._addr = addr
37 self._sock = socket.socket(family, socket.SOCK_DGRAM)
38 self._prefix = prefix
39 self._maxudpsize = maxudpsize
40
41 def _send(self, data):
42 """Send data to statsd."""
43 try:
44 self._sock.sendto(data.encode('ascii'), self._addr)
45 except (socket.error, RuntimeError):
46 # No time for love, Dr. Jones!
47 pass
48
49 def close(self):
50 if self._sock and hasattr(self._sock, 'close'):
51 self._sock.close()
52 self._sock = None
53
54 def pipeline(self):
55 return Pipeline(self)
@@ -0,0 +1,64
1 # -*- coding: utf-8 -*-
2
3 import logging
4 from sqlalchemy import *
5
6 from alembic.migration import MigrationContext
7 from alembic.operations import Operations
8
9 from rhodecode.lib.dbmigrate.versions import _reset_base
10 from rhodecode.model import meta, init_model_encryption
11
12
13 log = logging.getLogger(__name__)
14
15
16 def upgrade(migrate_engine):
17 """
18 Upgrade operations go here.
19 Don't create your own engine; bind migrate_engine to your metadata
20 """
21 _reset_base(migrate_engine)
22 from rhodecode.lib.dbmigrate.schema import db_4_20_0_0 as db
23
24 init_model_encryption(db)
25
26 # issue fixups
27 fixups(db, meta.Session)
28
29
30 def downgrade(migrate_engine):
31 meta = MetaData()
32 meta.bind = migrate_engine
33
34
35 def fixups(models, _SESSION):
36 # now create new changed value of clone_url
37 Optional = models.Optional
38
39 def get_by_name(cls, key):
40 return cls.query().filter(cls.app_settings_name == key).scalar()
41
42 def create_or_update(cls, key, val=Optional(''), type_=Optional('unicode')):
43 res = get_by_name(cls, key)
44 if not res:
45 val = Optional.extract(val)
46 type_ = Optional.extract(type_)
47 res = cls(key, val, type_)
48 else:
49 res.app_settings_name = key
50 if not isinstance(val, Optional):
51 # update if set
52 res.app_settings_value = val
53 if not isinstance(type_, Optional):
54 # update if set
55 res.app_settings_type = type_
56 return res
57
58 clone_uri_tmpl = models.Repository.DEFAULT_CLONE_URI_ID
59 print('settings new clone by url template to %s' % clone_uri_tmpl)
60
61 sett = create_or_update(models.RhodeCodeSetting,
62 'clone_uri_id_tmpl', clone_uri_tmpl, 'unicode')
63 _SESSION().add(sett)
64 _SESSION.commit()
@@ -0,0 +1,32
1 ## -*- coding: utf-8 -*-
2 <%inherit file="base.mako"/>
3
4 <%def name="subject()" filter="n,trim,whitespace_filter">
5 New Version of RhodeCode is available !
6 </%def>
7
8 ## plain text version of the email. Empty by default
9 <%def name="body_plaintext()" filter="n,trim">
10 A new version of RhodeCode is available!
11
12 Your version: ${current_ver}
13 New version: ${latest_ver}
14
15 Release notes:
16
17 https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html
18 </%def>
19
20 ## BODY GOES BELOW
21
22 <h3>A new version of RhodeCode is available!</h3>
23 <br/>
24 Your version: ${current_ver}<br/>
25 New version: <strong>${latest_ver}</strong><br/>
26
27 <h4>Release notes</h4>
28
29 <a href="https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html">
30 https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html
31 </a>
32
@@ -73,3 +73,5 90734aac31ee4563bbe665a43ff73190cc762275
73 a9655707f7cf4146affc51c12fe5ed8e02898a57 v4.23.0
73 a9655707f7cf4146affc51c12fe5ed8e02898a57 v4.23.0
74 56310d93b33b97535908ef9c7b0985b89bb7fad2 v4.23.1
74 56310d93b33b97535908ef9c7b0985b89bb7fad2 v4.23.1
75 7637c38528fa38c1eabc1fde6a869c20995a0da7 v4.23.2
75 7637c38528fa38c1eabc1fde6a869c20995a0da7 v4.23.2
76 6aeb4ac3ef7f0ac699c914740dad3688c9495e83 v4.24.0
77 6eaf953da06e468a4c4e5239d3d0e700bda6b163 v4.24.1
@@ -1,4 +1,4
1 |RCE| 4.23.0 |RNS|
1 |RCE| 4.24.0 |RNS|
2 ------------------
2 ------------------
3
3
4 Release Date
4 Release Date
@@ -16,14 +16,16 New Features
16 Can be used for backups etc.
16 Can be used for backups etc.
17 - Pull requests: expose commit versions in the pull-request commit list.
17 - Pull requests: expose commit versions in the pull-request commit list.
18
18
19
19 General
20 General
20 ^^^^^^^
21 ^^^^^^^
21
22
22 - Deps: bumped redis to 3.5.3
23 - Deps: bumped redis to 3.5.3
23 - rcextensions: improve examples
24 - Rcextensions: improve examples for some usage.
24 - Setup: added optional parameters to apply a default license, or skip re-creation of database at install.
25 - Setup: added optional parameters to apply a default license, or skip re-creation of database at install.
25 - Docs: update headers for NGINX
26 - Docs: update headers for NGINX
26 - Beaker cache: remove no longer used beaker cache init
27 - Beaker cache: remove no longer used beaker cache init
28 - Installation: the installer no longer requires gzip and bzip packages, and works on python 2 and 3
27
29
28
30
29 Security
31 Security
@@ -9,6 +9,7 Release Notes
9 .. toctree::
9 .. toctree::
10 :maxdepth: 1
10 :maxdepth: 1
11
11
12 release-notes-4.24.1.rst
12 release-notes-4.24.0.rst
13 release-notes-4.24.0.rst
13 release-notes-4.23.2.rst
14 release-notes-4.23.2.rst
14 release-notes-4.23.1.rst
15 release-notes-4.23.1.rst
@@ -274,6 +274,12 self: super: {
274 ];
274 ];
275 });
275 });
276
276
277 "pytest" = super."pytest".override (attrs: {
278 patches = [
279 ./patches/pytest/setuptools.patch
280 ];
281 });
282
277 # Avoid that base packages screw up the build process
283 # Avoid that base packages screw up the build process
278 inherit (basePythonPackages)
284 inherit (basePythonPackages)
279 setuptools;
285 setuptools;
@@ -48,7 +48,7 PYRAMID_SETTINGS = {}
48 EXTENSIONS = {}
48 EXTENSIONS = {}
49
49
50 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
50 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
51 __dbversion__ = 112 # defines current db version for migrations
51 __dbversion__ = 113 # defines current db version for migrations
52 __platform__ = platform.system()
52 __platform__ = platform.system()
53 __license__ = 'AGPLv3, and Commercial License'
53 __license__ = 'AGPLv3, and Commercial License'
54 __author__ = 'RhodeCode GmbH'
54 __author__ = 'RhodeCode GmbH'
@@ -384,6 +384,7 class AdminSettingsView(BaseAppView):
384 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
384 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
385 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
385 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
386 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
386 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
387 ('clone_uri_id_tmpl', 'rhodecode_clone_uri_id_tmpl', 'unicode'),
387 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
388 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
388 ('support_url', 'rhodecode_support_url', 'unicode'),
389 ('support_url', 'rhodecode_support_url', 'unicode'),
389 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
390 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
@@ -102,6 +102,11 Check if we should use full-topic or min
102 'date': datetime.datetime.now(),
102 'date': datetime.datetime.now(),
103 },
103 },
104
104
105 'update_available': {
106 'current_ver': '4.23.0',
107 'latest_ver': '4.24.0',
108 },
109
105 'exception': {
110 'exception': {
106 'email_prefix': '[RHODECODE ERROR]',
111 'email_prefix': '[RHODECODE ERROR]',
107 'exc_id': exc_traceback['exc_id'],
112 'exc_id': exc_traceback['exc_id'],
@@ -420,6 +420,27 class TestPullrequestsView(object):
420 assert pull_request.title == 'New title'
420 assert pull_request.title == 'New title'
421 assert pull_request.description == 'New description'
421 assert pull_request.description == 'New description'
422
422
423 def test_edit_title_description(self, pr_util, csrf_token):
424 pull_request = pr_util.create_pull_request()
425 pull_request_id = pull_request.pull_request_id
426
427 response = self.app.post(
428 route_path('pullrequest_update',
429 repo_name=pull_request.target_repo.repo_name,
430 pull_request_id=pull_request_id),
431 params={
432 'edit_pull_request': 'true',
433 'title': 'New title {} {2} {foo}',
434 'description': 'New description',
435 'csrf_token': csrf_token})
436
437 assert_session_flash(
438 response, u'Pull request title & description updated.',
439 category='success')
440
441 pull_request = PullRequest.get(pull_request_id)
442 assert pull_request.title_safe == 'New title {{}} {{2}} {{foo}}'
443
423 def test_edit_title_description_closed(self, pr_util, csrf_token):
444 def test_edit_title_description_closed(self, pr_util, csrf_token):
424 pull_request = pr_util.create_pull_request()
445 pull_request = pr_util.create_pull_request()
425 pull_request_id = pull_request.pull_request_id
446 pull_request_id = pull_request.pull_request_id
@@ -83,14 +83,10 class RepoSummaryView(RepoAppView):
83 if self._rhodecode_user.username != User.DEFAULT_USER:
83 if self._rhodecode_user.username != User.DEFAULT_USER:
84 username = safe_str(self._rhodecode_user.username)
84 username = safe_str(self._rhodecode_user.username)
85
85
86 _def_clone_uri = _def_clone_uri_id = c.clone_uri_tmpl
86 _def_clone_uri = c.clone_uri_tmpl
87 _def_clone_uri_id = c.clone_uri_id_tmpl
87 _def_clone_uri_ssh = c.clone_uri_ssh_tmpl
88 _def_clone_uri_ssh = c.clone_uri_ssh_tmpl
88
89
89 if '{repo}' in _def_clone_uri:
90 _def_clone_uri_id = _def_clone_uri.replace('{repo}', '_{repoid}')
91 elif '{repoid}' in _def_clone_uri:
92 _def_clone_uri_id = _def_clone_uri.replace('_{repoid}', '{repo}')
93
94 c.clone_repo_url = self.db_repo.clone_url(
90 c.clone_repo_url = self.db_repo.clone_url(
95 user=username, uri_tmpl=_def_clone_uri)
91 user=username, uri_tmpl=_def_clone_uri)
96 c.clone_repo_url_id = self.db_repo.clone_url(
92 c.clone_repo_url_id = self.db_repo.clone_url(
@@ -340,6 +340,10 def includeme(config, auth_resources=Non
340 'rhodecode.lib.request_counter.get_request_counter',
340 'rhodecode.lib.request_counter.get_request_counter',
341 'request_count')
341 'request_count')
342
342
343 config.add_request_method(
344 'rhodecode.lib._vendor.statsd.get_statsd_client',
345 'statsd', reify=True)
346
343 # Set the authorization policy.
347 # Set the authorization policy.
344 authz_policy = ACLAuthorizationPolicy()
348 authz_policy = ACLAuthorizationPolicy()
345 config.set_authorization_policy(authz_policy)
349 config.set_authorization_policy(authz_policy)
This diff has been collapsed as it changes many lines, (1706 lines changed) Show them Hide them
@@ -1,14 +1,14
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2020 RhodeCode GmbH
2 # Copyright (C) 2021 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 # FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
4 # FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
5 #
5 #
6 #, fuzzy
6 #, fuzzy
7 msgid ""
7 msgid ""
8 msgstr ""
8 msgstr ""
9 "Project-Id-Version: rhodecode-enterprise-ce 4.23.0\n"
9 "Project-Id-Version: rhodecode-enterprise-ce 4.24.0\n"
10 "Report-Msgid-Bugs-To: marcin@rhodecode.com\n"
10 "Report-Msgid-Bugs-To: marcin@rhodecode.com\n"
11 "POT-Creation-Date: 2020-11-23 09:00+0000\n"
11 "POT-Creation-Date: 2021-01-14 15:36+0000\n"
12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 "Language-Team: LANGUAGE <LL@li.org>\n"
14 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -22,41 +22,41 msgstr ""
22 msgid "posted a new {} comment"
22 msgid "posted a new {} comment"
23 msgstr ""
23 msgstr ""
24
24
25 #: rhodecode/apps/admin/views/defaults.py:90
25 #: rhodecode/apps/admin/views/defaults.py:82
26 msgid "Default settings updated successfully"
26 msgid "Default settings updated successfully"
27 msgstr ""
27 msgstr ""
28
28
29 #: rhodecode/apps/admin/views/defaults.py:108
29 #: rhodecode/apps/admin/views/defaults.py:100
30 msgid "Error occurred during update of default values"
30 msgid "Error occurred during update of default values"
31 msgstr ""
31 msgstr ""
32
32
33 #: rhodecode/apps/admin/views/exception_tracker.py:156
33 #: rhodecode/apps/admin/views/exception_tracker.py:146
34 msgid "Removed {} Exceptions"
34 msgid "Removed {} Exceptions"
35 msgstr ""
35 msgstr ""
36
36
37 #: rhodecode/apps/admin/views/exception_tracker.py:173
37 #: rhodecode/apps/admin/views/exception_tracker.py:160
38 msgid "Removed Exception {}"
38 msgid "Removed Exception {}"
39 msgstr ""
39 msgstr ""
40
40
41 #: rhodecode/apps/admin/views/permissions.py:121
41 #: rhodecode/apps/admin/views/permissions.py:114
42 msgid "Application permissions updated successfully"
42 msgid "Application permissions updated successfully"
43 msgstr ""
43 msgstr ""
44
44
45 #: rhodecode/apps/admin/views/permissions.py:142
45 #: rhodecode/apps/admin/views/permissions.py:135
46 #: rhodecode/apps/admin/views/permissions.py:218
46 #: rhodecode/apps/admin/views/permissions.py:205
47 #: rhodecode/apps/admin/views/permissions.py:320
47 #: rhodecode/apps/admin/views/permissions.py:298
48 msgid "Error occurred during update of permissions"
48 msgid "Error occurred during update of permissions"
49 msgstr ""
49 msgstr ""
50
50
51 #: rhodecode/apps/admin/views/permissions.py:198
51 #: rhodecode/apps/admin/views/permissions.py:185
52 msgid "Object permissions updated successfully"
52 msgid "Object permissions updated successfully"
53 msgstr ""
53 msgstr ""
54
54
55 #: rhodecode/apps/admin/views/permissions.py:300
55 #: rhodecode/apps/admin/views/permissions.py:278
56 msgid "Global permissions updated successfully"
56 msgid "Global permissions updated successfully"
57 msgstr ""
57 msgstr ""
58
58
59 #: rhodecode/apps/admin/views/permissions.py:485
59 #: rhodecode/apps/admin/views/permissions.py:448
60 #: rhodecode/templates/admin/gists/gist_show.mako:50
60 #: rhodecode/templates/admin/gists/gist_show.mako:50
61 #: rhodecode/templates/admin/integrations/list.mako:172
61 #: rhodecode/templates/admin/integrations/list.mako:172
62 #: rhodecode/templates/admin/my_account/my_account_profile.mako:7
62 #: rhodecode/templates/admin/my_account/my_account_profile.mako:7
@@ -75,548 +75,548 msgstr ""
75 #: rhodecode/templates/files/files_source.mako:39