Refactoring rsync_url according test failures
Change-Id: Ib815c322848024d6b0e945bf250988fe6d776fc5
diff --git a/trsync/objects/rsync_mirror.py b/trsync/objects/rsync_mirror.py
index 139f3f6..f7ab0ce 100644
--- a/trsync/objects/rsync_mirror.py
+++ b/trsync/objects/rsync_mirror.py
@@ -150,7 +150,7 @@
self.url.a_dir(self.snapshot_dir),
pattern=r'^{}-{}$'.format(
repo_name,
- self.timestamp.snapshot_stamp_regexp
+ self.timestamp.snapshot_stamp_pattern
)
)
links = self.ls_symlinks(self.url.a_dir())
diff --git a/trsync/objects/rsync_remote.py b/trsync/objects/rsync_remote.py
index 19cc01b..0ba4b0c 100644
--- a/trsync/objects/rsync_remote.py
+++ b/trsync/objects/rsync_remote.py
@@ -63,10 +63,10 @@
def _rsync_ls(self, dirname=None, pattern=r'.*', opts=''):
extra = '--no-v'
out = self._rsync_push(dest=dirname, opts=opts, extra=extra)
- regexp = re.compile(pattern)
+ pattern = re.compile(pattern)
out = [_ for _ in out.splitlines()
if (_.split()[-1] != '.') and
- (regexp.match(_.split()[-1]) is not None)]
+ (pattern.match(_.split()[-1]) is not None)]
return out
def ls(self, dirname=None, pattern=r'.*'):
diff --git a/trsync/objects/rsync_url.py b/trsync/objects/rsync_url.py
index f86bd96..af15da0 100644
--- a/trsync/objects/rsync_url.py
+++ b/trsync/objects/rsync_url.py
@@ -1,4 +1,4 @@
-#-*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import os
import re
@@ -20,174 +20,122 @@
self._url = remote_url
self._url_type = False
+ self._sep = '/'
- self.regexps = {
+ self.pattern_tpls = {
+ 'protocol': r'((?P<protocol>^[^/:]+)://)',
+ 'user': r'((?P<user>[^@/:]+)@)',
+ 'host': r'(?P<host>[^@:/]+)',
+ 'port': r'(:(?P<port>[^@:/]+))',
+ 'module': r'((?P<module>[^@:/]+)/?)',
+ 'path': r'(?P<path>[^@:]*$)',
+ }
+
+ self.patterns = {
# ssh: [USER@]HOST:SRC
'ssh': re.compile(
- r'^'
- r'(?P<user>[-\w]+@)?'
- r'(?P<host>[-\.\w]+){1}'
- r':'
- r'(?P<path>(~{0,1}[\w/-]*)){1}'
- r'$'
+ '^{user}?{host}:(?!//){path}?$'
+ ''.format(**self.pattern_tpls)
),
# rsync: [USER@]HOST::SRC
'rsync1': re.compile(
- r'^'
- r'(?P<user>[-\w]+@)?'
- r'(?P<host>[-\.\w]+){1}'
- r'::'
- r'(?P<module>[\w-]+){1}'
- r'(?P<path>[\w/-]*)?'
- r'$'
+ '^{user}?{host}(::(?!/){module}?){path}?$'
+ ''.format(**self.pattern_tpls)
),
# rsync://[USER@]HOST[:PORT]/SRC
'rsync2': re.compile(
- r'^rsync://'
- r'(?P<user>[-\w]+@)?'
- r'(?P<host>[-\.\w]+){1}'
- r'(?P<port>:[\d]+)?'
- r'(?P<module>/[\w-]*)?'
- r'(?P<path>[\w/-]*)?'
- r'$'
+ '^{protocol}{user}?{host}{port}?(/{module})?{path}?$'
+ ''.format(**self.pattern_tpls)
),
# local/path/to/directory
'path': re.compile(
- r'^'
- r'(?P<path>(~{0,1}[\w/-]+)){1}'
- r'$'
+ '^{path}$'
+ ''.format(**self.pattern_tpls)
),
}
- self._match = self._get_matching_regexp()
+ self.templates = {
+ # ssh: [USER@]HOST:SRC
+ 'ssh': ('{user}@', '{host}:', '{path}'),
+ # rsync: [USER@]HOST::SRC
+ 'rsync1': ('{user}@', '{host}::', '{module}', '/{path}'),
+ # rsync://[USER@]HOST[:PORT]/SRC
+ 'rsync2': ('{protocol}://', '{user}@', '{host}', ':{port}',
+ '/{module}', '/{path}'),
+ # local/path/to/directory
+ 'path': ('{path}', ),
+ }
+
+ self._match = self._get_matching_pattern()
if self.match is None:
- self.user, self.host, self.module, self.port, self.path = \
- None, None, None, None, None
- self._root = self.url_dir()
+ self._parsed_url = utils.bunch()
+ self._parsed_url.protocol = None,
+ self._parsed_url.user = None,
+ self._parsed_url.host = None,
+ self._parsed_url.port = None,
+ self._parsed_url.module = None,
+ self._parsed_url.path = None,
else:
self._parse_rsync_url(self.match)
- def _get_matching_regexp(self):
- regexps = self._get_all_matching_regexps()
- regexps_len = len(regexps)
- #if regexps_len > 1:
- # raise Exception('Rsync location {} matches with {} regexps {}'
- # ''.format(self.url, len(regexps), str(regexps)))
- # TODO: Possible may be better remove this raise and keep
- # only warning with request to fail bug. rsync will parse this
- # remote later
- if regexps_len != 1:
- logger.warn('Rsync location "{}" matches with {} regexps: {}.'
- 'Please fail a bug on {} if it is wrong.'
- ''.format(self.url, len(regexps), str(regexps), '...'))
- if regexps_len == 0:
+ def _get_matching_pattern(self):
+ patterns = self._get_all_matching_patterns()
+ patterns_len = len(patterns)
+ if patterns_len != 1:
+ logger.warn('Rsync location "{}" matches with {} patterns: {}.'
+ 'Please file a bug on {} if it is wrong.'
+ ''.format(self.url,
+ len(patterns),
+ [str(_.pattern) for _ in patterns],
+ '...'))
+ if patterns_len == 0:
self._url_type = None
return None
else:
- return regexps[0]
+ return patterns[0]
- def _get_all_matching_regexps(self):
- regexps = list()
- for url_type, regexp in self.regexps.items():
- match = regexp.match(self.url)
+ def _get_all_matching_patterns(self):
+ patterns = list()
+ for url_type, pattern in self.patterns.items():
+ match = pattern.match(self.url)
if match is not None:
if self.url_type is False:
self._url_type = url_type
- regexps.append(regexp)
- return regexps
+ patterns.append(pattern)
+ return patterns
- def _parse_rsync_url(self, regexp):
+ def _parse_rsync_url(self, pattern):
# parse remote url
- for match in re.finditer(regexp, self._url):
-
- self.path = match.group('path')
- if self.path is None:
- self.path = ''
-
- try:
- self.host = match.group('host')
- except IndexError:
- self.host = None
-
- try:
- self.user = match.group('user')
- except IndexError:
- self.user = None
- else:
- if self.user is not None:
- self.user = self.user.strip('@')
-
- try:
- self.port = match.group('port')
- except IndexError:
- self.port = None
- else:
- if self.port is not None:
- self.port = int(self.port.strip(':'))
-
- try:
- self.module = match.group('module')
- except IndexError:
- self.module = None
- else:
- if self.module is not None:
- self.module = self.module.strip('/')
- if not self.module:
- self.module = None
+ match = pattern.match(self._url)
+ self._parsed_url = utils.bunch(match.groupdict())
if self.url_type == 'ssh':
- if self.path == '':
- self.path = '~'
+ if self._parsed_url.path == '':
+ self._parsed_url.path = '~'
if self.path.startswith('/'):
- self._rootpath = '/'
+ self._parsed_url.rootpath = '/'
else:
- self._rootpath = '~/'
-
- self._netloc = '{}:'.format(self.url.split(':')[0])
- self._root = '{}{}'.format(self._netloc, self._rootpath)
- self._url = '{}{}'.format(self._netloc, self.path)
+ self._parsed_url.rootpath = '~/'
elif self.url_type.startswith('rsync'):
- if self.path == '':
- self.path = '/'
- self._rootpath = '/'
+ if self._parsed_url.module:
+ if self._parsed_url.path == '':
+ self._parsed_url.path = '/'
+ self._parsed_url.rootpath = '/'
+ else:
+ self._parsed_url.path = None
- if self.url_type == 'rsync1':
- root_parts = ['{}::'.format(self.url.split('::')[0])]
- if self.module is not None:
- root_parts.append('{}'.format(self.module))
-
- elif self.url_type == 'rsync2':
- root_parts = ['rsync://']
- if self.user is not None:
- root_parts.append('{}@'.format(self.user))
- root_parts.append('{}'.format(self.host))
- if self.port is not None:
- root_parts.append(':{}'.format(self.port))
- if self.module is not None:
- root_parts.append('/{}'.format(self.module))
-
- self._netloc = ''.join(root_parts)
- if self.module is not None:
- root_parts.append('{}'.format(self._rootpath))
- self._root = ''.join(root_parts)
- self._url = '{}{}'.format(self._netloc, self.path)
+ if self.url_type == 'rsync2':
+ if self.protocol != 'rsync':
+ msg = 'Wrong URL protocol == "{}"'.format(self.protocol)
+ logger.error(msg)
+ raise Exception(msg)
elif self.url_type == 'path':
- if self.path == '':
- self.path = '.'
- self._rootpath = self.a_dir(self.path)
- self._netloc = None
- self._root = self._rootpath
- self._url = '{}'.format(self.path)
-
- else:
- self._netloc = None
- self._root = self._url
- self._url = '{}'.format(self._rootpath)
-
+ self._sep = os.path.sep
+ self._parsed_url.rootpath = self.a_dir(self.path)
@property
def match(self):
@@ -198,6 +146,94 @@
return self._url_type
@property
+ def url(self):
+ return self._url
+
+ @property
+ def protocol(self):
+ return self._parsed_url.get('protocol', None)
+
+ @property
+ def user(self):
+ return self._parsed_url.get('user', None)
+
+ @property
+ def host(self):
+ return self._parsed_url.get('host', None)
+
+ @property
+ def port(self):
+ return self._parsed_url.get('port', None)
+
+ @property
+ def module(self):
+ return self._parsed_url.get('module', None)
+
+ @property
+ def path(self):
+ return self._parsed_url.get('path', '')
+
+ @property
+ def sep(self):
+ return self._sep
+
+ @property
+ def root(self):
+
+ templates = {
+ # ssh: [USER@]HOST:SRC
+ 'ssh': ('{user}@', '{host}:', '{rootpath}'),
+ # rsync: [USER@]HOST::SRC
+ 'rsync1': ('{user}@', '{host}::', '{module}'),
+ # rsync://[USER@]HOST[:PORT]/SRC
+ 'rsync2': ('{protocol}://', '{user}@', '{host}', ':{port}',
+ '/{module}'),
+ # local/path/to/directory
+ 'path': ('{rootpath}', ),
+ }
+ return self.by_template(templates[self.url_type])
+
+ @property
+ def netloc(self):
+
+ templates = {
+ # ssh: [USER@]HOST:SRC
+ 'ssh': ('{user}@', '{host}:'),
+ # rsync: [USER@]HOST::SRC
+ 'rsync1': ('{user}@', '{host}::', '{module}'),
+ # rsync://[USER@]HOST[:PORT]/SRC
+ 'rsync2': ('{protocol}://', '{user}@', '{host}', ':{port}',
+ '/{module}'),
+ # local/path/to/directory
+ 'path': ('', ),
+ }
+ return self.by_template(templates[self.url_type])
+
+ @property
+ def parsed_url(self):
+ if self.url_type is None:
+ return None
+ parsed_dict = utils.bunch()
+ for part in ('protocol', 'user', 'host', 'port', 'module', 'path',
+ 'rootpath'):
+ for tplpart in self.templates[self.url_type]:
+ if '{' + part + '}' in tplpart:
+ value = self._parsed_url.get(part)
+ if value:
+ parsed_dict[part] = value
+ return parsed_dict
+
+ def by_template(self, template_list):
+ template = ''
+ for part in ('protocol', 'user', 'host', 'port', 'module', 'path',
+ 'rootpath'):
+ for tplpart in template_list:
+ if '{' + part + '}' in tplpart:
+ if self._parsed_url.get(part):
+ template += tplpart
+ return template.format(**self._parsed_url)
+
+ @property
def is_valid(self):
if self.match is None:
return False
@@ -213,10 +249,11 @@
def _fn_join(self, *parts):
''' Joins filenames with ignoring empty parts (None, '', etc)'''
+
parts = [_ for _ in parts if _]
if len(parts) > 0:
- if parts[-1].endswith(os.path.sep):
+ if parts[-1].endswith(self.sep):
isdir = True
else:
isdir = False
@@ -227,31 +264,24 @@
if first is None:
first = ''
if len(first) > 1:
- while first.endswith(os.path.sep):
+ while first.endswith(self.sep):
first = first[:-1]
- subs = os.path.sep.join([_ for _ in parts if _]).split(os.path.sep)
+ subs = self.sep.join([_ for _ in parts if _]).split(self.sep)
subs = [_ for _ in subs if _]
- result = re.sub(r'^//', r'/', os.path.sep.join([first, ] + subs))
+ result = re.sub(r'^//', r'/', self.sep.join([first, ] + subs))
result = re.sub(r'([^:])//', r'\1/', result)
- if not result.endswith(os.path.sep) and isdir:
- result += os.path.sep
+ if not result.endswith(self.sep) and isdir:
+ result += self.sep
return result
- @property
- def url(self):
- return self._url
-
- @property
- def root(self):
- return self._root
-
def join(self, *parts):
return self._fn_join(*parts)
def urljoin(self, *parts):
- return self.join(self.url, *parts)
+ return self.join(self.by_template(self.templates[self.url_type]),
+ *parts)
def a_dir(self, *path):
result = self._fn_join(*path)
@@ -260,14 +290,16 @@
return result
def url_dir(self, *path):
- return self.a_dir(self.url, *path)
+ return self.a_dir(self.by_template(self.templates[self.url_type]),
+ *path)
def a_file(self, *path):
result = self._fn_join(*path)
if len(result) > 1:
- while result.endswith(os.path.sep):
+ while result.endswith(self.sep):
result = result[:-1]
return result
def url_file(self, *path):
- return self.a_file(self.url, *path)
+ return self.a_file(self.by_template(self.templates[self.url_type]),
+ *path)
diff --git a/trsync/tests/test_rsync_url.py b/trsync/tests/test_rsync_url.py
index 9ba305e..751ab77 100644
--- a/trsync/tests/test_rsync_url.py
+++ b/trsync/tests/test_rsync_url.py
@@ -1,4 +1,4 @@
-#-*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import os
import unittest
@@ -25,8 +25,8 @@
logger.info('For "{}" should be {}'.format(remote, expected_result))
url = rsync_url.RsyncUrl(remote)
self.log_locals(url)
- matching_regexps = url._get_all_matching_regexps()
- self.assertEqual(len(matching_regexps), expected_result)
+ matching_patterns = url._get_all_matching_patterns()
+ self.assertEqual(len(matching_patterns), expected_result)
def classed(self, remote, expected_result):
logger.info('For "{}" should be {}'.format(remote, expected_result))
@@ -64,12 +64,24 @@
self.log_locals(url)
self.assertEqual(url.url, expected_result)
+ def parsed_url(self, remote, expected_result):
+ logger.info('For "{}" should be {}'.format(remote, expected_result))
+ url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
+ self.assertEqual(url.parsed_url, expected_result)
+
def root(self, remote, expected_result):
logger.info('For "{}" should be {}'.format(remote, expected_result))
url = rsync_url.RsyncUrl(remote)
self.log_locals(url)
self.assertEqual(url.root, expected_result)
+ def netloc(self, remote, expected_result):
+ logger.info('For "{}" should be {}'.format(remote, expected_result))
+ url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
+ self.assertEqual(url.netloc, expected_result)
+
def urljoin(self, remote, expected_result):
logger.info('For "{}" should be {}'.format(remote, expected_result))
url = rsync_url.RsyncUrl(remote)
diff --git a/trsync/tests/test_rsync_url.yaml b/trsync/tests/test_rsync_url.yaml
index efdd764..496f9bd 100644
--- a/trsync/tests/test_rsync_url.yaml
+++ b/trsync/tests/test_rsync_url.yaml
@@ -9,7 +9,12 @@
'ubuntu@172.18.66.89:~/':
url: 'ubuntu@172.18.66.89:~/'
+ parsed_url:
+ user: 'ubuntu'
+ host: '172.18.66.89'
+ path: '~/'
root: 'ubuntu@172.18.66.89:~/'
+ netloc: 'ubuntu@172.18.66.89:'
urljoin:
null: 'ubuntu@172.18.66.89:~/'
'': 'ubuntu@172.18.66.89:~/'
@@ -56,8 +61,13 @@
'ubuntu@172.18.66.89:':
- url: 'ubuntu@172.18.66.89:~'
+ url: 'ubuntu@172.18.66.89:'
+ parsed_url:
+ user: 'ubuntu'
+ host: '172.18.66.89'
+ path: '~'
root: 'ubuntu@172.18.66.89:~/'
+ netloc: 'ubuntu@172.18.66.89:'
urljoin:
null: 'ubuntu@172.18.66.89:~'
'': 'ubuntu@172.18.66.89:~'
@@ -87,7 +97,12 @@
'ubuntu@172.18.66.89:sub/dir':
url: 'ubuntu@172.18.66.89:sub/dir'
+ parsed_url:
+ user: 'ubuntu'
+ host: '172.18.66.89'
+ path: 'sub/dir'
root: 'ubuntu@172.18.66.89:~/'
+ netloc: 'ubuntu@172.18.66.89:'
urljoin:
null: 'ubuntu@172.18.66.89:sub/dir'
'': 'ubuntu@172.18.66.89:sub/dir'
@@ -117,7 +132,12 @@
'ubuntu@172.18.66.89:~':
url: 'ubuntu@172.18.66.89:~'
+ parsed_url:
+ user: 'ubuntu'
+ host: '172.18.66.89'
+ path: '~'
root: 'ubuntu@172.18.66.89:~/'
+ netloc: 'ubuntu@172.18.66.89:'
urljoin:
null: 'ubuntu@172.18.66.89:~'
'': 'ubuntu@172.18.66.89:~'
@@ -147,7 +167,12 @@
'ubuntu@172.18.66.89:~/sub/dir/':
url: 'ubuntu@172.18.66.89:~/sub/dir/'
+ parsed_url:
+ user: 'ubuntu'
+ host: '172.18.66.89'
+ path: '~/sub/dir/'
root: 'ubuntu@172.18.66.89:~/'
+ netloc: 'ubuntu@172.18.66.89:'
urljoin:
null: 'ubuntu@172.18.66.89:~/sub/dir/'
'': 'ubuntu@172.18.66.89:~/sub/dir/'
@@ -177,7 +202,12 @@
'ubuntu@172.18.66.89:~/sub/dir':
url: 'ubuntu@172.18.66.89:~/sub/dir'
+ parsed_url:
+ user: 'ubuntu'
+ host: '172.18.66.89'
+ path: '~/sub/dir'
root: 'ubuntu@172.18.66.89:~/'
+ netloc: 'ubuntu@172.18.66.89:'
urljoin:
null: 'ubuntu@172.18.66.89:~/sub/dir'
'': 'ubuntu@172.18.66.89:~/sub/dir'
@@ -207,7 +237,12 @@
'ubuntu@172.18.66.89:/':
url: 'ubuntu@172.18.66.89:/'
+ parsed_url:
+ user: 'ubuntu'
+ host: '172.18.66.89'
+ path: '/'
root: 'ubuntu@172.18.66.89:/'
+ netloc: 'ubuntu@172.18.66.89:'
urljoin:
null: 'ubuntu@172.18.66.89:/'
'': 'ubuntu@172.18.66.89:/'
@@ -237,7 +272,12 @@
'johnivanov@172.18.66.89:/mirror-sync/otlichniy/reg/exp':
url: 'johnivanov@172.18.66.89:/mirror-sync/otlichniy/reg/exp'
+ parsed_url:
+ user: 'johnivanov'
+ host: '172.18.66.89'
+ path: '/mirror-sync/otlichniy/reg/exp'
root: 'johnivanov@172.18.66.89:/'
+ netloc: 'johnivanov@172.18.66.89:'
exact_match_num: 1
classed: 'ssh'
parsed:
@@ -249,7 +289,11 @@
'172.18.66.89:/mirror-sync/otlichniy/reg/exp':
url: '172.18.66.89:/mirror-sync/otlichniy/reg/exp'
+ parsed_url:
+ host: '172.18.66.89'
+ path: '/mirror-sync/otlichniy/reg/exp'
root: '172.18.66.89:/'
+ netloc: '172.18.66.89:'
exact_match_num: 1
classed: 'ssh'
parsed:
@@ -261,7 +305,11 @@
'172.18.66.89:/':
url: '172.18.66.89:/'
+ parsed_url:
+ host: '172.18.66.89'
+ path: '/'
root: '172.18.66.89:/'
+ netloc: '172.18.66.89:'
exact_match_num: 1
classed: 'ssh'
parsed:
@@ -272,8 +320,12 @@
'172.18.66.89:':
- url: '172.18.66.89:~'
+ url: '172.18.66.89:'
+ parsed_url:
+ host: '172.18.66.89'
+ path: '~'
root: '172.18.66.89:~/'
+ netloc: '172.18.66.89:'
exact_match_num: 1
classed: 'ssh'
parsed:
@@ -285,7 +337,13 @@
'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp':
url: 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp'
- root: 'johnivanov@172.18.66.89::mirror-sync/'
+ parsed_url:
+ user: 'johnivanov'
+ host: '172.18.66.89'
+ module: 'mirror-sync'
+ path: 'otlichniy/reg/exp'
+ root: 'johnivanov@172.18.66.89::mirror-sync'
+ netloc: 'johnivanov@172.18.66.89::mirror-sync'
urljoin:
null: 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp'
'': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp'
@@ -311,13 +369,18 @@
- '172.18.66.89'
- null
- 'mirror-sync'
- - '/otlichniy/reg/exp'
+ - 'otlichniy/reg/exp'
valid: True
'172.18.66.89::mirror-sync/otlichniy/reg/exp':
url: '172.18.66.89::mirror-sync/otlichniy/reg/exp'
- root: '172.18.66.89::mirror-sync/'
+ parsed_url:
+ host: '172.18.66.89'
+ module: 'mirror-sync'
+ path: 'otlichniy/reg/exp'
+ root: '172.18.66.89::mirror-sync'
+ netloc: '172.18.66.89::mirror-sync'
exact_match_num: 1
classed: 'rsync1'
parsed_rsync:
@@ -325,13 +388,18 @@
- '172.18.66.89'
- null
- 'mirror-sync'
- - '/otlichniy/reg/exp'
+ - 'otlichniy/reg/exp'
valid: True
'172.18.66.89::mirror-sync/':
url: '172.18.66.89::mirror-sync/'
- root: '172.18.66.89::mirror-sync/'
+ parsed_url:
+ host: '172.18.66.89'
+ module: 'mirror-sync'
+ path: '/'
+ root: '172.18.66.89::mirror-sync'
+ netloc: '172.18.66.89::mirror-sync'
exact_match_num: 1
classed: 'rsync1'
parsed_rsync:
@@ -344,8 +412,13 @@
'172.18.66.89::mirror-sync':
- url: '172.18.66.89::mirror-sync/'
- root: '172.18.66.89::mirror-sync/'
+ url: '172.18.66.89::mirror-sync'
+ parsed_url:
+ host: '172.18.66.89'
+ module: 'mirror-sync'
+ path: '/'
+ root: '172.18.66.89::mirror-sync'
+ netloc: '172.18.66.89::mirror-sync'
exact_match_num: 1
classed: 'rsync1'
parsed_rsync:
@@ -359,6 +432,7 @@
'johnivanov@172.18.66.89::/mirror-sync/otlichniy/reg/exp':
url: 'johnivanov@172.18.66.89::/mirror-sync/otlichniy/reg/exp'
+ parsed_url: null
exact_match_num: 0
classed: null
valid: False
@@ -366,6 +440,7 @@
'172.18.66.89::/mirror-sync/otlichniy/reg/exp':
url: '172.18.66.89::/mirror-sync/otlichniy/reg/exp'
+ parsed_url: null
exact_match_num: 0
classed: null
valid: False
@@ -373,6 +448,7 @@
'172.18.66.89::/':
url: '172.18.66.89::/'
+ parsed_url: null
exact_match_num: 0
classed: null
valid: False
@@ -380,6 +456,8 @@
'172.18.66.89::':
url: '172.18.66.89::'
+ parsed_url:
+ host: '172.18.66.89'
exact_match_num: 1
classed: 'rsync1'
parsed_rsync:
@@ -387,14 +465,22 @@
- '172.18.66.89'
- null
- null
- - '/'
+ - null
valid: False
'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp':
url: 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp'
- root: 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/'
+ parsed_url:
+ protocol: 'rsync'
+ user: 'mirror-sync'
+ host: '172.18.66.89'
+ port: '7327'
+ module: 'otlichniy'
+ path: 'reg/exp'
+ root: 'rsync://mirror-sync@172.18.66.89:7327/otlichniy'
+ netloc: 'rsync://mirror-sync@172.18.66.89:7327/otlichniy'
urljoin:
null: 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp'
'': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp'
@@ -418,29 +504,42 @@
parsed_rsync:
- 'mirror-sync'
- '172.18.66.89'
- - 7327
+ - '7327'
- 'otlichniy'
- - '/reg/exp'
+ - 'reg/exp'
valid: True
'rsync://172.18.66.89:7327/mirror-sync/otlichniy/reg/exp':
url: 'rsync://172.18.66.89:7327/mirror-sync/otlichniy/reg/exp'
- root: 'rsync://172.18.66.89:7327/mirror-sync/'
+ parsed_url:
+ protocol: 'rsync'
+ host: '172.18.66.89'
+ port: '7327'
+ module: 'mirror-sync'
+ path: 'otlichniy/reg/exp'
+ root: 'rsync://172.18.66.89:7327/mirror-sync'
+ netloc: 'rsync://172.18.66.89:7327/mirror-sync'
exact_match_num: 1
classed: 'rsync2'
parsed_rsync:
- null
- '172.18.66.89'
- - 7327
+ - '7327'
- 'mirror-sync'
- - '/otlichniy/reg/exp'
+ - 'otlichniy/reg/exp'
valid: True
'rsync://172.18.66.89/mirror-sync/otlichniy/reg/exp':
url: 'rsync://172.18.66.89/mirror-sync/otlichniy/reg/exp'
- root: 'rsync://172.18.66.89/mirror-sync/'
+ parsed_url:
+ protocol: 'rsync'
+ host: '172.18.66.89'
+ module: 'mirror-sync'
+ path: 'otlichniy/reg/exp'
+ root: 'rsync://172.18.66.89/mirror-sync'
+ netloc: 'rsync://172.18.66.89/mirror-sync'
exact_match_num: 1
classed: 'rsync2'
parsed_rsync:
@@ -448,13 +547,19 @@
- '172.18.66.89'
- null
- 'mirror-sync'
- - '/otlichniy/reg/exp'
+ - 'otlichniy/reg/exp'
valid: True
'rsync://172.18.66.89/mirror-sync/':
url: 'rsync://172.18.66.89/mirror-sync/'
- root: 'rsync://172.18.66.89/mirror-sync/'
+ parsed_url:
+ protocol: 'rsync'
+ host: '172.18.66.89'
+ module: 'mirror-sync'
+ path: '/'
+ root: 'rsync://172.18.66.89/mirror-sync'
+ netloc: 'rsync://172.18.66.89/mirror-sync'
exact_match_num: 1
classed: 'rsync2'
parsed_rsync:
@@ -468,7 +573,11 @@
'rsync://172.18.66.89/':
url: 'rsync://172.18.66.89/'
+ parsed_url:
+ protocol: 'rsync'
+ host: '172.18.66.89'
root: 'rsync://172.18.66.89'
+ netloc: 'rsync://172.18.66.89'
exact_match_num: 1
classed: 'rsync2'
parsed_rsync:
@@ -476,13 +585,17 @@
- '172.18.66.89'
- null
- null
- - '/'
+ - null
valid: False
'rsync://172.18.66.89':
- url: 'rsync://172.18.66.89/'
+ url: 'rsync://172.18.66.89'
+ parsed_url:
+ protocol: 'rsync'
+ host: '172.18.66.89'
root: 'rsync://172.18.66.89'
+ netloc: 'rsync://172.18.66.89'
exact_match_num: 1
classed: 'rsync2'
parsed_rsync:
@@ -490,13 +603,16 @@
- '172.18.66.89'
- null
- null
- - '/'
+ - null
valid: False
'/':
url: '/'
+ parsed_url:
+ path: '/'
root: '/'
+ netloc: ''
urljoin:
null: '/'
'': '/'
@@ -526,7 +642,10 @@
'dir':
url: 'dir'
+ parsed_url:
+ path: 'dir'
root: 'dir/'
+ netloc: ''
exact_match_num: 1
classed: 'path'
parsed:
@@ -538,7 +657,10 @@
'/dir':
url: '/dir'
+ parsed_url:
+ path: '/dir'
root: '/dir/'
+ netloc: ''
exact_match_num: 1
classed: 'path'
parsed:
@@ -550,7 +672,10 @@
'/dir/subdir/':
url: '/dir/subdir/'
+ parsed_url:
+ path: '/dir/subdir/'
root: '/dir/subdir/'
+ netloc: ''
exact_match_num: 1
classed: 'path'
parsed:
@@ -558,3 +683,31 @@
- null
- '/dir/subdir/'
valid: True
+
+
+'rsync://localhost/mirror-sync/mos-repos/centos/mos9.0-centos7':
+ url: 'rsync://localhost/mirror-sync/mos-repos/centos/mos9.0-centos7'
+ parsed_url:
+ protocol: 'rsync'
+ host: 'localhost'
+ module: 'mirror-sync'
+ path: 'mos-repos/centos/mos9.0-centos7'
+ root: 'rsync://localhost/mirror-sync'
+ netloc: 'rsync://localhost/mirror-sync'
+ exact_match_num: 1
+ classed: 'rsync2'
+ valid: True
+
+
+'rsync://localhost/mirror-sync/mos-repos/ubuntu':
+ url: 'rsync://localhost/mirror-sync/mos-repos/ubuntu'
+ parsed_url:
+ protocol: 'rsync'
+ host: 'localhost'
+ module: 'mirror-sync'
+ path: 'mos-repos/ubuntu'
+ root: 'rsync://localhost/mirror-sync'
+ netloc: 'rsync://localhost/mirror-sync'
+ exact_match_num: 1
+ classed: 'rsync2'
+ valid: True
diff --git a/trsync/utils/utils.py b/trsync/utils/utils.py
index d95165a..cdd4bcb 100644
--- a/trsync/utils/utils.py
+++ b/trsync/utils/utils.py
@@ -55,7 +55,7 @@
def __init__(self, now=None):
# now='2015-06-18-104259'
self.snapshot_stamp_format = r'%Y-%m-%d-%H%M%S'
- self.snapshot_stamp_regexp = r'[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}'
+ self.snapshot_stamp_pattern = r'[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}'
if now is None:
self.now = datetime.datetime.utcnow()
@@ -125,3 +125,9 @@
raise ResultNotProduced('Result "{}" was not produced during '
'{} attempts.'
''.format(expected_result, attempt - 1))
+
+
+class bunch(dict):
+ def __init__(self, *args, **kwargs):
+ super(bunch, self).__init__(*args, **kwargs)
+ self.__dict__ = self