blob: 38836ac7ba0ffcfc60273dead07d092549a4d9bc [file] [log] [blame]
Max Rasskazovb07aacb2015-05-29 19:54:52 +03001#-*- coding: utf-8 -*-
2
3import logging
4import re
5
6logging.basicConfig(level='INFO')
7logger = logging.getLogger('RsyncUrl')
8
9
10class RsyncUrl(object):
11
12 def __init__(self, remote_url):
13
14 self.url = remote_url
15 self._url_type = False
16
17 self.regexps = {
18 # ssh: [USER@]HOST:SRC
19 'ssh': re.compile(
20 r'^'
21 r'(?P<user>[-\w]+@)?'
22 r'(?P<host>[-\.\w]+){1}'
23 r':'
Max Rasskazov95e001b2015-05-30 23:53:22 +030024 r'(?P<path>(~{0,1}[\w/-]*)){1}'
Max Rasskazovb07aacb2015-05-29 19:54:52 +030025 r'$'
26 ),
27 # rsync: [USER@]HOST::SRC
28 'rsync1': re.compile(
29 r'^'
30 r'(?P<user>[-\w]+@)?'
31 r'(?P<host>[-\.\w]+){1}'
32 r'::'
33 r'(?P<path>[\w/-]*){1}'
34 r'$'
35 ),
36 # rsync://[USER@]HOST[:PORT]/SRC
37 'rsync2': re.compile(
38 r'^rsync://'
39 r'(?P<user>[-\w]+@)?'
40 r'(?P<host>[-\.\w]+){1}'
41 r'(?P<port>:[\d]+)?'
42 r'(?P<path>[\w/-]*){1}'
43 r'$'
44 ),
45 # local/path/to/directory
46 'path': re.compile(
47 r'^'
Max Rasskazov95e001b2015-05-30 23:53:22 +030048 r'(?P<path>(~{0,1}[\w/-]+)){1}'
Max Rasskazovb07aacb2015-05-29 19:54:52 +030049 r'$'
50 ),
51 }
52
53 self.match = self._get_matching_regexp()
54 if self.match is None:
55 self.user, self.host, self.port, self.path = None, None, None, None
56 else:
57 self._parse_rsync_url(self.match)
58
59 def _get_matching_regexp(self):
60 regexps = self._get_all_matching_regexps()
61 regexps_len = len(regexps)
62 #if regexps_len > 1:
63 # raise Exception('Rsync location {} matches with {} regexps {}'
64 # ''.format(self.url, len(regexps), str(regexps)))
65 # TODO: Possible may be better remove this raise and keep
66 # only warning with request to fail bug. rsync will parse this
67 # remote later
68 if regexps_len != 1:
69 logger.warn('Rsync location "{}" matches with {} regexps: {}.'
70 'Please fail a bug on {} if it is wrong.'
71 ''.format(self.url, len(regexps), str(regexps), '...'))
72 if regexps_len == 0:
73 self._url_type = None
74 return None
75 else:
76 return regexps[0]
77
78 def _get_all_matching_regexps(self):
79 regexps = list()
80 for url_type, regexp in self.regexps.items():
81 match = regexp.match(self.url)
82 if match is not None:
83 if self.url_type is False:
84 self._url_type = url_type
85 regexps.append(regexp)
86 #print match, regexp.pattern
87 return regexps
88
89 def _parse_rsync_url(self, regexp):
90 # parse remote url
91
92 for match in re.finditer(regexp, self.url):
93
94 self.path = match.group('path')
95 if not self.path:
96 self.path = '/'
97
98 try:
99 self.host = match.group('host')
100 except IndexError:
101 self.host = None
102
103 try:
104 self.user = match.group('user')
105 except IndexError:
106 self.user = None
107 else:
108 if self.user is not None:
109 self.user = self.user.strip('@')
110
111 try:
112 self.port = match.group('port')
113 except IndexError:
114 self.port = None
115 else:
116 if self.port is not None:
117 self.port = int(self.port.strip(':'))
118
119 @property
120 def url_type(self):
121 return self._url_type