def test_url_15(url0, url0b, url1): # 4b) join method, with URL as input parameter url2 = URL.objectify(url1) url6 = url1.join(URL.objectify(url2)) assert url6 == url1 url6b = url6.join(url0) url6c = url6.join(url0b) url6d = url6.join(None) for url6alt in (url6b, url6c, url6d): assert url6 == url6alt
async def ainit(self): """Method called after construction in order to asynchronously init the object. no args, only asynchronous. """ # backwards compatibility. if self._url is not None: self.url = self.client.url.join(URL.objectify(self._url)) else: self.url = self.client.url await asyncio.sleep(1) cup = await self.get_properties([dav.CurrentUserPrincipal()]) self.url = self.client.url.join( URL.objectify(cup['{DAV:}current-user-principal'])) return self
def __init__(self, client=None, url=None, parent=None, name=None, id=None, **extra): """ Default constructor. Parameters: * client: A DAVClient instance * url: The url for this object. May be a full URL or a relative URL. * parent: The parent object - used when creating objects * name: A displayname * id: The resource id (UID for an Event) """ if client is None and parent is not None: client = parent.client self.client = client self.parent = parent self.name = name self.id = id self.extra_init_options = extra # url may be a path relative to the caldav root if client and url: self.url = client.url.join(url) else: self.url = URL.objectify(url)
def test_url_16(url1, url3): url7 = url1.join(URL.objectify(url3)) assert url7 == "http://*****:*****@www.example.com:8080/bar" assert url7.username == 'foo' assert url7.is_auth() is True # 7) unauth() strips username/password assert url7.unauth() == 'http://www.example.com:8080/bar'
def _calendar_home_setter(self, url): # TODO: Handle when url is None ? if isinstance(url, CalendarSet): self._calendar_home_set = url return url sanitized_url = URL.objectify(url) if (sanitized_url.hostname and sanitized_url.hostname != self.client.url.hostname): # icloud (and others?) having a load balanced system, # where each principal resides on one named host self.client.url = sanitized_url self._calendar_home_set = CalendarSet( self.client, self.client.url.join(sanitized_url)) return self._calendar_home_set
async def save(self): """ The save method for a calendar is only used to create it, for now. We know we have to create it when we don't have a url. Returns: * self """ if self.url is None: await self._create(name=self.name, id=self.id, **self.extra_init_options) if not self.url.endswith('/'): self.url = URL.objectify(str(self.url) + '/') return self
async def object_by_uid(self, uid, comp_filter=None): """ Get one event from the calendar. Parameters: * uid: the event uid Returns: * Event() or None """ data = cdav.CalendarData() prop = dav.Prop() + data query = cdav.TextMatch(uid) query = cdav.PropFilter("UID") + query if comp_filter: query = comp_filter + query vcalendar = cdav.CompFilter("VCALENDAR") + query filter = cdav.Filter() + vcalendar root = cdav.CalendarQuery() + [prop, filter] response = await self._query(root, 1, 'report') if response.status == 404: raise error.NotFoundError(errmsg(response)) elif response.status == 400: raise error.ReportError(errmsg(response)) items_found = response.tree.findall(".//" + dav.Response.tag) for r in items_found: href = unquote(r.find(".//" + dav.Href.tag).text) data = unquote(r.find(".//" + cdav.CalendarData.tag).text) # Ref Lucas Verney, we've actually done a substring search, if the # uid given in the query is short (i.e. just "0") we're likely to # get false positives back from the server. # # Long uids are folded, so splice the lines together here before # attempting a match. item_uid = re.search(r'\nUID:((.|\n[ \t])*)\n', data) if (not item_uid or re.sub(r'\n[ \t]', '', item_uid.group(1)) != uid): continue return self._calendar_comp_class_by_data(data)( self.client, url=URL.objectify(href), data=data, parent=self) raise error.NotFoundError(errmsg(response))
async def _create(self, data, id=None, path=None, new=False): if id is None and path is not None and str(path).endswith('.ics'): id = re.search('(/|^)([^/]*).ics', str(path)).group(2) elif id is None: for obj_type in ('vevent', 'vtodo', 'vjournal', 'vfreebusy', 'vavailability'): obj = None if hasattr(self.instance, obj_type): obj = getattr(self.instance, obj_type) elif self.instance.name.lower() == obj_type: obj = self.instance if obj is not None: id = obj.uid.value break else: for obj_type in ('vevent', 'vtodo', 'vjournal', 'vfreebusy', 'vavailability'): obj = None if hasattr(self.instance, obj_type): obj = getattr(self.instance, obj_type) elif self.instance.name.lower() == obj_type: obj = self.instance if obj is not None: if not hasattr(obj, 'uid'): obj.add('uid') obj.uid = id break if path is None and id is not None: path = id + ".ics" if path is None and id is None: raise error.PutError("Nothing to do: no content") path = self.parent.url.join(path) headers = {"Content-Type": 'text/calendar; charset="utf-8"'} if new: headers["If-None-Match"] = "*" else: headers["If-Match"] = "*" r = await self.client.put(path, data, headers) if r.status == 302: path = [x[1] for x in r.headers if x[0] == 'location'][0] elif not (r.status in (204, 201)): raise error.PutError(errmsg(r)) self.url = URL.objectify(path) self.id = id
def __init__(self, url, proxy=None, username=None, password=None, auth=None, ssl_verify_cert=None): """ Sets up a HTTPConnection object towards the server in the url. Parameters: * url: A fully qualified url: `scheme://user:pass@hostname:port` * proxy: A string defining a proxy server: `hostname:port` * username and password should be passed as arguments or in the URL * auth and ssl_verify_cert is passed to aiohttp.request. ** ssl_verify_cert can be None (default verify) or False or a ssl.SSLContext """ log.debug("url: " + str(url)) self.url = URL.objectify(url) # Prepare proxy info if proxy is not None: self.proxy = proxy # library expects the proxy url to have a scheme if re.match('^.*://', proxy) is None: self.proxy = self.url.scheme + '://' + proxy # add a port is one is not specified # TODO: this will break if using basic auth and embedding # username:password in the proxy URL p = self.proxy.split(":") if len(p) == 2: self.proxy += ':8080' log.debug("init - proxy: %s" % (self.proxy)) # Build global headers self.headers = {"User-Agent": "Mozilla/5.0", "Content-Type": "text/xml", "Accept": "text/xml"} if self.url.username is not None: username = unquote(self.url.username) password = unquote(self.url.password) self.username = username self.password = password self.auth = auth # TODO: it's possible to force through a specific auth method here, # but no test code for this. self.ssl_verify_cert = ssl_verify_cert self.url = self.url.unauth() log.debug("self.url: " + str(url))
def calendar(self, name=None, cal_id=None): """ The calendar method will return a calendar object. It will not initiate any communication with the server. Parameters: * name: return the calendar with this name * cal_id: return the calendar with this calendar id Returns: * Calendar(...)-object """ cal = Calendar(self.client, name=name, parent=self, url=self.url.join(cal_id), id=cal_id) # check url for consistency with Calendar.save() method if not cal.url.endswith('/'): cal.url = URL.objectify(str(cal.url) + '/') return cal
def url3(request): return URL.objectify("/bar")
def url0(request): return URL.objectify(None)
def test_url_18(url1, url5): url9 = url1.join(URL.objectify(url5)) assert url9 == "http://*****:*****@www.example.com:8080/bar"
def test_url_10(url1): url4 = URL.objectify(urlparse(str(url1))) url8 = url1.join(url4) assert url8 == url1
def test_url_8(url1): # 4) join method url2 = URL.objectify(url1) url6 = url1.join(url2) assert url6 == url1
def test_url_6(url1): url4 = URL.objectify(urlparse(str(url1))) assert str(url4) == LONG_URL
def test_url_2(url1): url4 = URL.objectify(urlparse(str(url1))) assert url1 == url4
def test_url_1(url1): # 1) URL.objectify should return a valid URL object almost no matter # what's thrown in url2 = URL.objectify(url1) assert url1 == url2 assert url2.path == '/caldav.php/'
def test_url_19(url1): urlA = url1.join(URL.objectify("someuser/calendar")) assert urlA == "http://*****:*****@www.example.com:8080/caldav.php/someuser/calendar"
def url1(request): return URL.objectify(LONG_URL)
def test_url_22(url1): urlC = URL.objectify("https://www.example.com:443/foo") assert urlC.port == 443 # 6) is_auth returns True if the URL contains a username. assert urlC.is_auth() is False
def url0b(request): return URL.objectify("")
def test_url_20(url1, url5): urlB = url5.join(URL.objectify(url1)) assert urlB == url1
def url5(request): return URL.objectify(urlparse("/bar"))
async def request(self, url, method="GET", body="", headers={}): """ Actually sends the request """ # objectify the url url = URL.objectify(url) proxy = None if self.proxy is not None: proxy = self.proxy log.debug("using proxy - %s", proxy) # ensure that url is a unicode string url = str(url) combined_headers = dict(self.headers) combined_headers.update(headers) if body is None or body == "" and "Content-Type" in combined_headers: del combined_headers["Content-Type"] log.debug( "sending request - method={0}, url={1}, headers={2}\nbody:\n{3}" .format(method, url, combined_headers, body)) print("sending request - method={0}, url={1}, headers={2}\nbody:\n{3}" .format(method, url, combined_headers, body)) auth = None # digest auth is not (yet) supported by aiohttp, so skip it for now # if self.auth is None and self.username is not None: # auth = aiohttp.HTTPDigestAuth(self.username, self.password) # else: # auth = self.auth # async with aiohttp.ClientSession() as client: # r = await client.request( # method, url, data=to_wire(body), # headers=combined_headers, proxy=proxy, # auth=auth, ssl=self.ssl_verify_cert) # response = DAVResponse() # await response.load(r) # If server supports BasicAuth and not DigestAuth, let's try again: # if response.status == 401 and self.auth is None and auth is not None: if self.auth is None and self.username is not None: auth = aiohttp.BasicAuth(self.username, self.password) else: auth = self.auth # TODO: Define total timeout in config ? async with aiohttp.ClientSession( timeout=aiohttp.ClientTimeout(total=30)) as client: r = await client.request( method, url, data=to_wire(body), headers=combined_headers, proxy=proxy, auth=auth, ssl=self.ssl_verify_cert) response = DAVResponse() await response.load(r) # this is an error condition the application wants to know if response.status in (401, 403): # forbidden or unauthorized ex = error.AuthorizationError() ex.url = url ex.reason = response.reason raise ex # let's save the auth object and remove the user/pass information if not self.auth and auth: self.auth = auth del self.username del self.password return response