Exemplo n.º 1
0
 def __delitem__(self, key):
     entity = self.new_entity()
     entity.SetKey(key)
     request = http.HTTPRequest(str(entity.GetLocation()), 'DELETE')
     self.client.ProcessRequest(request)
     if request.status == 204:
         # success, nothing to read back
         return
     else:
         self.RaiseError(request)
Exemplo n.º 2
0
    def LoadService(self, serviceRoot):
        """Configures this client to use the service at *serviceRoot*
		
		*serviceRoot* is a string or :py:class:`pyslet.rfc2396.URI` instance."""
        if isinstance(serviceRoot, uri.URI):
            self.serviceRoot = serviceRoot
        else:
            self.serviceRoot = uri.URIFactory.URI(serviceRoot)
        request = http.HTTPRequest(str(self.serviceRoot))
        request.SetHeader('Accept', 'application/atomsvc+xml')
        self.ProcessRequest(request)
        if request.status != 200:
            raise UnexpectedHTTPResponse(
                "%i %s" % (request.status, request.response.reason))
        doc = core.Document(baseURI=self.serviceRoot)
        doc.Read(request.resBody)
        if isinstance(doc.root, app.Service):
            self.service = doc.root
            self.serviceRoot = uri.URIFactory.URI(doc.root.ResolveBase())
            self.feeds = {}
            self.model = None
            for w in self.service.Workspace:
                for f in w.Collection:
                    url = f.GetFeedURL()
                    if f.Title:
                        self.feeds[f.Title.GetValue()] = url
        else:
            raise InvalidServiceDocument(str(serviceRoot))
        self.pathPrefix = self.serviceRoot.absPath
        if self.pathPrefix[-1] == u"/":
            self.pathPrefix = self.pathPrefix[:-1]
        metadata = uri.URIFactory.Resolve(serviceRoot, '$metadata')
        doc = edmx.Document(baseURI=metadata, reqManager=self)
        defaultContainer = None
        try:
            doc.Read()
            if isinstance(doc.root, edmx.Edmx):
                self.model = doc.root
                for s in self.model.DataServices.Schema:
                    for container in s.EntityContainer:
                        if container.IsDefaultEntityContainer():
                            prefix = ""
                            defaultContainer = container
                        else:
                            prefix = container.name + "."
                        for es in container.EntitySet:
                            fTitle = prefix + es.name
                            if fTitle in self.feeds:
                                if self.feeds[fTitle] == es.GetLocation():
                                    self.feeds[fTitle] = es
            else:
                raise DataFormatError(str(metadata))
        except xml.XMLError, e:
            # Failed to read the metadata document, there may not be one of course
            raise DataFormatError(str(e))
Exemplo n.º 3
0
 def GetStreamGenerator(self):
     """A generator function that yields blocks (strings) of data from the entity's media stream."""
     streamURL = str(self.GetLocation()) + "/$value"
     request = http.HTTPRequest(str(streamURL), 'GET')
     request.SetHeader('Accept', '*/*')
     self.client.ProcessRequest(request)
     if request.status == 404:
         return
     elif request.status != 200:
         raise UnexpectedHTTPResponse(
             "%i %s" % (request.status, request.response.reason))
     yield request.resBody
Exemplo n.º 4
0
 def GetStreamSize(self):
     """Returns the size of the entity's media stream in bytes by issuing a HEAD request."""
     streamURL = str(self.GetLocation()) + "/$value"
     request = http.HTTPRequest(str(streamURL), 'HEAD')
     request.SetHeader('Accept', '*/*')
     self.client.ProcessRequest(request)
     if request.status == 404:
         return None
     elif request.status != 200:
         raise UnexpectedHTTPResponse(
             "%i %s" % (request.status, request.response.reason))
     return request.response.GetContentLength()
Exemplo n.º 5
0
 def entity_generator(self):
     feedURL = self.baseURI
     sysQueryOptions = {}
     if self.filter is not None:
         sysQueryOptions[
             core.SystemQueryOption.filter] = unicode(self.filter)
     if self.expand is not None:
         sysQueryOptions[
             core.SystemQueryOption.expand] = core.FormatExpand(self.expand)
     if self.select is not None:
         sysQueryOptions[
             core.SystemQueryOption.select] = core.FormatSelect(self.select)
     if self.orderby is not None:
         sysQueryOptions[
             core.SystemQueryOption.orderby] = core.CommonExpression.OrderByToString(
             self.orderby)
     if sysQueryOptions:
         feedURL = uri.URIFactory.URI(
             str(feedURL) +
             "?" +
             core.ODataURI.FormatSysQueryOptions(sysQueryOptions))
     while True:
         request = http.HTTPRequest(str(feedURL))
         request.SetHeader('Accept', 'application/atom+xml')
         self.client.ProcessRequest(request)
         if request.status != 200:
             raise UnexpectedHTTPResponse(
                 "%i %s" % (request.status, request.response.reason))
         doc = core.Document(baseURI=feedURL)
         doc.Read(request.resBody)
         if isinstance(doc.root, atom.Feed):
             if len(doc.root.Entry):
                 for e in doc.root.Entry:
                     entity = core.Entity(self.entity_set)
                     entity.exists = True
                     e.GetValue(entity)
                     yield entity
             else:
                 break
         else:
             raise core.InvalidFeedDocument(str(feedURL))
         feedURL = None
         for link in doc.root.Link:
             if link.rel == "next":
                 feedURL = link.ResolveURI(link.href)
                 break
         if feedURL is None:
             break
Exemplo n.º 6
0
 def __getitem__(self, key):
     if self.isCollection:
         return super(NavigationCollection, self).__getitem__(key)
     else:
         # The baseURI points to a single entity already, we must not add
         # the key
         entityURL = str(self.baseURI)
         sysQueryOptions = {}
         if self.filter is not None:
             sysQueryOptions[
                 core.SystemQueryOption.filter] = unicode(self.filter)
         if self.expand is not None:
             sysQueryOptions[
                 core.SystemQueryOption.expand] = core.FormatExpand(
                 self.expand)
         if self.select is not None:
             sysQueryOptions[
                 core.SystemQueryOption.select] = core.FormatSelect(
                 self.select)
         if sysQueryOptions:
             entityURL = uri.URIFactory.URI(
                 entityURL +
                 "?" +
                 core.ODataURI.FormatSysQueryOptions(sysQueryOptions))
         request = http.HTTPRequest(str(entityURL))
         request.SetHeader('Accept', 'application/atom+xml;type=entry')
         self.client.ProcessRequest(request)
         if request.status == 404:
             raise KeyError(key)
         elif request.status != 200:
             raise UnexpectedHTTPResponse(
                 "%i %s" % (request.status, request.response.reason))
         doc = core.Document(baseURI=entityURL)
         doc.Read(request.resBody)
         if isinstance(doc.root, atom.Entry):
             entity = core.Entity(self.entity_set)
             entity.exists = True
             doc.root.GetValue(entity)
             if entity.Key() == key:
                 return entity
             else:
                 raise KeyError(key)
         elif isinstance(doc.root, core.Error):
             raise KeyError(key)
         else:
             raise core.InvalidEntryDocument(str(entityURL))
Exemplo n.º 7
0
def runWeatherLoader(container=None):
    """Starts a thread that monitors the DTG website for new values"""
    if container is None:
        doc = LoadMetadata()
        container = MakeContainer(doc)
    client = http.HTTPRequestManager()
    weatherData = container['DataPoints']
    DTG = "http://www.cl.cam.ac.uk/research/dtg/weather/daily-text.cgi?%s"
    with weatherData.OpenCollection() as collection:
        collection.set_orderby(
            core.CommonExpression.OrderByFromString('TimePoint desc'))
        sleepInterval = 60
        collection.set_page(1)
        lastPoint = list(collection.iterpage())
        if lastPoint:
            lastPoint = lastPoint[0]['TimePoint'].value
        else:
            lastPoint = iso.TimePoint.FromString("19950630T000000Z")
        nextDay = lastPoint.date
        while True:
            today = iso.TimePoint.FromNowUTC().date
            if nextDay < today:
                # Load in nextDay
                logging.info("Requesting data for %s", str(nextDay))
                century, year, month, day = nextDay.GetCalendarDay()
                request = http.HTTPRequest(DTG % str(nextDay))
                client.ProcessRequest(request)
                if request.status == 200:
                    # process this file and move on to the next day
                    f = StringIO.StringIO(request.resBody)
                    LoadDataFromFile(weatherData, f, century * 100 + year,
                                     month, day)
                    nextDay = nextDay.Offset(days=1)
                    if sleepInterval > 10:
                        sleepInterval = sleepInterval // 2
                else:
                    # back off and try again
                    sleepInterval = sleepInterval * 2
            else:
                # back off and try again
                sleepInterval = sleepInterval * 2
            client.IdleCleanup(0)
            if sleepInterval > 86400:
                sleepInterval = 86400
            time.sleep(sleepInterval)
Exemplo n.º 8
0
 def InsertEntity(self, entity):
     if entity.exists:
         raise edm.EntityExists(str(entity.GetLocation()))
     doc = core.Document(root=core.Entry(None, entity))
     data = str(doc)
     request = http.HTTPRequest(str(self.baseURI), 'POST', reqBody=data)
     request.SetContentType(
         http.MediaType.FromString(core.ODATA_RELATED_ENTRY_TYPE))
     self.client.ProcessRequest(request)
     if request.status == 201:
         # success, read the entity back from the response
         doc = core.Document()
         doc.Read(request.resBody)
         entity.exists = True
         doc.root.GetValue(entity)
         # so which bindings got handled?  Assume all of them
         for k, dv in entity.NavigationItems():
             dv.bindings = []
     else:
         self.RaiseError(request)
Exemplo n.º 9
0
 def replace(self, entity):
     if not entity.exists:
         raise edm.NonExistentEntity(str(entity.GetLocation()))
     if self.isCollection:
         # inherit the implementation
         super(NavigationCollection, self).replace(entity)
     else:
         if not isinstance(entity, edm.Entity) or entity.entity_set is not self.entity_set:
             raise TypeError
         doc = core.Document(root=core.URI)
         doc.root.SetValue(str(entity.GetLocation()))
         data = str(doc)
         request = http.HTTPRequest(str(self.linksURI), 'PUT', reqBody=data)
         request.SetContentType(
             http.MediaType.FromString('application/xml'))
         self.client.ProcessRequest(request)
         if request.status == 204:
             return
         else:
             self.RaiseError(request)
Exemplo n.º 10
0
 def __len__(self):
     # use $count
     feedURL = self.baseURI
     sysQueryOptions = {}
     if self.filter is not None:
         sysQueryOptions[core.SystemQueryOption.filter] = unicode(
             self.filter)
     if sysQueryOptions:
         feedURL = uri.URIFactory.URI(
             str(feedURL) + "/$count?" +
             core.ODataURI.FormatSysQueryOptions(sysQueryOptions))
     else:
         feedURL = uri.URIFactory.URI(str(feedURL) + "/$count")
     request = http.HTTPRequest(str(feedURL))
     request.SetHeader('Accept', 'text/plain')
     self.client.ProcessRequest(request)
     if request.status == 200:
         return int(request.resBody)
     else:
         raise UnexpectedHTTPResponse(
             "%i %s" % (request.status, request.response.reason))
Exemplo n.º 11
0
 def iterpage(self, setNextPage=False):
     feedURL = self.baseURI
     sysQueryOptions = {}
     if self.filter is not None:
         sysQueryOptions[core.SystemQueryOption.filter] = unicode(
             self.filter)
     if self.expand is not None:
         sysQueryOptions[core.SystemQueryOption.expand] = core.FormatExpand(
             self.expand)
     if self.select is not None:
         sysQueryOptions[core.SystemQueryOption.select] = core.FormatSelect(
             self.select)
     if self.orderby is not None:
         sysQueryOptions[core.SystemQueryOption.
                         orderby] = core.CommonExpression.OrderByToString(
                             self.orderby)
     if self.top is not None:
         sysQueryOptions[core.SystemQueryOption.top] = unicode(self.top)
     if self.skip is not None:
         sysQueryOptions[core.SystemQueryOption.skip] = unicode(self.skip)
     if self.skiptoken is not None:
         sysQueryOptions[core.SystemQueryOption.skiptoken] = self.skiptoken
     if sysQueryOptions:
         feedURL = uri.URIFactory.URI(
             str(feedURL) + "?" +
             core.ODataURI.FormatSysQueryOptions(sysQueryOptions))
     request = http.HTTPRequest(str(feedURL))
     request.SetHeader('Accept', 'application/atom+xml')
     self.client.ProcessRequest(request)
     if request.status != 200:
         raise UnexpectedHTTPResponse(
             "%i %s" % (request.status, request.response.reason))
     doc = core.Document(baseURI=feedURL)
     doc.Read(request.resBody)
     if isinstance(doc.root, atom.Feed):
         if len(doc.root.Entry):
             for e in doc.root.Entry:
                 entity = core.Entity(self.entitySet)
                 entity.exists = True
                 e.GetValue(entity)
                 yield entity
         feedURL = self.nextSkiptoken = None
         for link in doc.root.Link:
             if link.rel == "next":
                 feedURL = link.ResolveURI(link.href)
                 break
         if feedURL is not None:
             # extract the skiptoken from this link
             feedURL = core.ODataURI(feedURL, self.client.pathPrefix)
             self.nextSkiptoken = feedURL.sysQueryOptions.get(
                 core.SystemQueryOption.skiptoken, None)
         if setNextPage:
             if self.nextSkiptoken is not None:
                 self.skiptoken = self.nextSkiptoken
                 self.skip = None
             elif self.skip is not None:
                 self.skip += len(doc.root.Entry)
             else:
                 self.skip = len(doc.root.Entry)
     else:
         raise core.InvalidFeedDocument(str(feedURL))
Exemplo n.º 12
0
    def LoadService(self, serviceRoot):
        """Configures this client to use the service at *serviceRoot*

        *serviceRoot* is a string or :py:class:`pyslet.rfc2396.URI` instance."""
        if isinstance(serviceRoot, uri.URI):
            self.serviceRoot = serviceRoot
        else:
            self.serviceRoot = uri.URIFactory.URI(serviceRoot)
        request = http.HTTPRequest(str(self.serviceRoot))
        request.SetHeader('Accept', 'application/atomsvc+xml')
        self.ProcessRequest(request)
        if request.status != 200:
            raise UnexpectedHTTPResponse(
                "%i %s" % (request.status, request.response.reason))
        doc = core.Document(baseURI=self.serviceRoot)
        doc.Read(request.resBody)
        if isinstance(doc.root, app.Service):
            self.service = doc.root
            self.serviceRoot = uri.URIFactory.URI(doc.root.ResolveBase())
            self.feeds = {}
            self.model = None
            for w in self.service.Workspace:
                for f in w.Collection:
                    url = f.GetFeedURL()
                    if f.Title:
                        self.feeds[f.Title.GetValue()] = url
        else:
            raise InvalidServiceDocument(str(serviceRoot))
        self.pathPrefix = self.serviceRoot.absPath
        if self.pathPrefix[-1] == u"/":
            self.pathPrefix = self.pathPrefix[:-1]
        metadata = uri.URIFactory.Resolve(serviceRoot, '$metadata')
        doc = edmx.Document(baseURI=metadata, reqManager=self)
        defaultContainer = None
        try:
            doc.Read()
            if isinstance(doc.root, edmx.Edmx):
                self.model = doc.root
                for s in self.model.DataServices.Schema:
                    for container in s.EntityContainer:
                        if container.IsDefaultEntityContainer():
                            prefix = ""
                            defaultContainer = container
                        else:
                            prefix = container.name + "."
                        for es in container.EntitySet:
                            fTitle = prefix + es.name
                            if fTitle in self.feeds:
                                if self.feeds[fTitle] == es.GetLocation():
                                    self.feeds[fTitle] = es
            else:
                raise DataFormatError(str(metadata))
        except xml.XMLError as e:
            # Failed to read the metadata document, there may not be one of
            # course
            raise DataFormatError(str(e))
        # Missing feeds are pruned from the list, perhaps the service advertises them
        # but if we don't have a model of them we can't use of them
        for f in self.feeds.keys():
            if isinstance(self.feeds[f], uri.URI):
                logging.info(
                    "Can't find metadata definition of feed: %s", str(
                        self.feeds[f]))
                del self.feeds[f]
            else:
                # Bind our EntityCollection class
                entity_set = self.feeds[f]
                entity_set.Bind(EntityCollection, client=self)
                for np in entity_set.entityType.NavigationProperty:
                    entity_set.BindNavigation(
                        np.name, NavigationCollection, client=self)
                logging.debug(
                    "Registering feed: %s", str(self.feeds[f].GetLocation()))