Exemple #1
0
def getFrontPage(config):
    """ Returns a front page for the WMS, containing example links """
    doc = StringIO()
    doc.write("<html><head><title>%s</title></head>" % config.title)
    doc.write("<body><h1>%s</h1>" % config.title)
    doc.write("<p><a href=\"" + prefix + "?SERVICE=WMS&REQUEST=GetCapabilities\">Capabilities document</a></p>")
    doc.write("<p><a href=\"./godiva2.html\">Godiva2 interface</a></p>")
    doc.write("<h2>Datasets:</h2>")
    # Print a GetMap link for every dataset we have
    doc.write("<table border=\"1\"><tbody>")
    doc.write("<tr><th>Dataset</th>")
    for format in getmap.getSupportedImageFormats():
        doc.write("<th>%s</th>" % format)
    if config.allowFeatureInfo:
        doc.write("<th>FeatureInfo</th>")
    doc.write("</tr>")
    datasets = config.datasets
    for ds in datasets.keys():
        doc.write("<tr><th>%s</th>" % datasets[ds].title)
        vars = datareader.getVariableMetadata(datasets[ds].location)
        for format in getmap.getSupportedImageFormats():
            doc.write("<td>")
            for varID in vars.keys():
                doc.write("<a href=\"WMS.py?SERVICE=WMS&REQUEST=GetMap&VERSION=1.3.0&STYLES=&CRS=CRS:84&WIDTH=256&HEIGHT=256&FORMAT=%s" % format)
                doc.write("&LAYERS=%s%s%s" % (ds, wmsUtils.getLayerSeparator(), varID))
                bbox = vars[varID].bbox
                doc.write("&BBOX=%s,%s,%s,%s" % tuple([str(b) for b in bbox]))
                if vars[varID].tvalues is not None:
                    doc.write("&TIME=%s" % iso8601.tostring(vars[varID].tvalues[-1]))
                doc.write("\">%s</a><br />" % vars[varID].title)
            doc.write("</td>")
        if config.allowFeatureInfo:
            doc.write("<td>")
            if datasets[ds].queryable:
                for varID in vars.keys():
                    doc.write("<a href=\"WMS.py?SERVICE=WMS&REQUEST=GetFeatureInfo&VERSION=1.3.0&CRS=CRS:84&WIDTH=256&HEIGHT=256&INFO_FORMAT=text/xml")
                    doc.write("&QUERY_LAYERS=%s%s%s" % (ds, wmsUtils.getLayerSeparator(), varID))
                    bbox = vars[varID].bbox
                    doc.write("&BBOX=%s,%s,%s,%s" % tuple([str(b) for b in bbox]))
                    doc.write("&I=128&J=128")
                    if vars[varID].tvalues is not None:
                        doc.write("&TIME=%s" % iso8601.tostring(vars[varID].tvalues[-1]))
                    doc.write("\">%s</a><br />" % vars[varID].title)
            else:
                doc.write("Dataset not queryable")
            doc.write("</td>")
        doc.write("</tr>")
    doc.write("</tbody></table>")
    doc.write("</body></html>")
    s = doc.getvalue()
    doc.close()
    return s
Exemple #2
0
def _getMonthAfter(date):
    """ Returns an ISO8601-formatted date that is exactly one month later than
        the given date """
    if date[1] == 12:
        month = 1
        year = date[0] + 1
    else:
        month = date[1] + 1
        year = date[0]
    newDate = tuple([year] + [month] + list(date[2:]))
    return iso8601.tostring(time.mktime(newDate))
Exemple #3
0
    def init_props_from_gce (self, gce):
        self._snarf_itemid_from_gce(gce)
        self._snarf_names_gender_from_gce(gce)
        self._snarf_notes_from_gce(gce)
        self._snarf_emails_from_gce(gce)
        self._snarf_postal_from_gce(gce)
        self._snarf_org_details_from_gce(gce)
        self._snarf_phones_and_faxes_from_gce(gce)
        self._snarf_dates_from_gce(gce)
        self._snarf_websites_from_gce(gce)
        self._snarf_ims_from_gce(gce)
        self._snarf_sync_tags_from_gce(gce)

        self._snarf_custom_props_from_gce(gce)

        # Google entries do not have a created entry. We should just set it to
        # the current time, and take it from there.
        if not self.get_created():
            self.set_created(iso8601.tostring(time.time()))
            self.set_updated(iso8601.tostring(time.time()))
Exemple #4
0
def timestampToIso8601(date):
	d = iso8601.tostring(date)
	if (len(d) == 24 or string.find(d, "Z") == -1):
		# YYYY-MM-DDThh:mm:ss with +/-hh:mm
		# or any other with +/-hh:mm
		return d

	if (len(d) == 20):
		# YYYY-MM-DDThh:mm:ssZ
		return string.replace(d, "Z", ".000Z")

	return string.replace(d, "Z", ":00.000Z")
Exemple #5
0
def timestampToIso8601(date):
    d = iso8601.tostring(date)
    if (len(d) == 24 or string.find(d, "Z") == -1):
        # YYYY-MM-DDThh:mm:ss with +/-hh:mm
        # or any other with +/-hh:mm
        return d

    if (len(d) == 20):
        # YYYY-MM-DDThh:mm:ssZ
        return string.replace(d, "Z", ".000Z")

    return string.replace(d, "Z", ":00.000Z")
Exemple #6
0
    def _snarf_dates_from_olprops(self, olpd):
        d = self._get_olprop(olpd, mt.PR_CREATION_TIME)
        if d:
            date = utils.utc_time_to_local_ts(d)
            self.set_created(iso8601.tostring(date))

        d = self._get_olprop(olpd, mt.PR_BIRTHDAY)
        if d:
            d = utils.utc_time_to_local_ts(d, ret_dt=True)
            date = utils.pytime_to_yyyy_mm_dd(d)
            self.set_birthday(date)

        a = self._get_olprop(olpd, mt.PR_WEDDING_ANNIVERSARY)
        if a:
            a = utils.utc_time_to_local_ts(a, ret_dt=True)
            date = utils.pytime_to_yyyy_mm_dd(a)
            self.set_anniv(date)
Exemple #7
0
    def _snarf_dates_from_olprops (self, olpd):
        d = self._get_olprop(olpd, mt.PR_CREATION_TIME)
        if d:
            date = utils.utc_time_to_local_ts(d)
            self.set_created(iso8601.tostring(date))
        
        d = self._get_olprop(olpd, mt.PR_BIRTHDAY)
        if d:
            d = utils.utc_time_to_local_ts(d, ret_dt=True)
            date = utils.pytime_to_yyyy_mm_dd(d)
            self.set_birthday(date)

        a = self._get_olprop(olpd, mt.PR_WEDDING_ANNIVERSARY)
        if a:
            a = utils.utc_time_to_local_ts(a, ret_dt=True)
            date = utils.pytime_to_yyyy_mm_dd(a)
            self.set_anniv(date)
Exemple #8
0
def getTimesteps(config, dataset, varID, tIndex):
    """ Returns an HTML select box allowing the user to select a 
        set of times for a given day """
    datasets = config.datasets
    # Get an array of time axis values in seconds since the epoch
    tValues = datareader.getVariableMetadata(datasets[dataset].location)[varID].tvalues
    # TODO: is this the right thing to do here?
    if tValues is None:
        return ""
    str = StringIO()
    
    # We find a list of indices of timesteps that are on the same day
    # as the provided tIndex
    indices = {}
    reftime = time.gmtime(tValues[tIndex])
    indices[tIndex] = "%02d:%02d:%02d" % (reftime[3], reftime[4], reftime[5])
    for i in xrange(tIndex + 1, len(tValues)):
        t = time.gmtime(tValues[i])
        diff = _compareDays(reftime, t)
        if diff == 0:
            indices[i] = "%02d:%02d:%02d" % (t[3], t[4], t[5])
        else:
            break
    for i in xrange(tIndex - 1, -1, -1): # count backwards through the axis indices to zero
        t = time.gmtime(tValues[i])
        diff = _compareDays(reftime, t)
        if diff == 0:
            indices[i] = "%02d:%02d:%02d" % (t[3], t[4], t[5])
        else:
            break

    # Write the selection box with the timesteps
    str.write("<select id=\"tValues\" onchange=\"javascript:updateMap()\">")
    keys = indices.keys()
    keys.sort()
    for i in keys:
        str.write("<option value=\"%s\">%s</option>" % (iso8601.tostring(tValues[i]), indices[i]))
    str.write("</select>")

    s = str.getvalue()
    str.close()
    return s
Exemple #9
0
def getCapabilities(req, params, config, lastUpdateTime):
    """ Returns the Capabilities document.
        req = mod_python request object or WMS.FakeModPythonRequest object
        params = wmsUtils.RequestParser object containing the request parameters
        config = ConfigParser object containing configuration info for this WMS
        lastUpdateTime = time at which cache of data and metadata was last updated """

    version = params.getParamValue("version", "")
    format = params.getParamValue("format", "")
    # TODO: deal with version and format

    # Check the UPDATESEQUENCE (used for cache consistency)
    updatesequence = params.getParamValue("updatesequence", "")
    if updatesequence != "":
        try:
            us = iso8601.parse(updatesequence)
            if round(us) == round(lastUpdateTime):
                # Equal to the nearest second
                raise CurrentUpdateSequence(updatesequence)
            elif us > lastUpdateTime:
                raise InvalidUpdateSequence(updatesequence)
        except ValueError:
            # Client didn't supply a valid ISO8601 date
            # According to the spec, InvalidUpdateSequence is not the
            # right error code here so we use a generic exception
            raise WMSException("UPDATESEQUENCE must be a valid ISO8601 date")

    output = StringIO()
    output.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
    output.write("<WMS_Capabilities version=\"" + wmsUtils.getWMSVersion() + "\"")
    # UpdateSequence is accurate to the nearest second
    output.write(" updateSequence=\"%s\"" % iso8601.tostring(round(lastUpdateTime)))
    output.write(" xmlns=\"http://www.opengis.net/wms\"")
    output.write(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"")
    # The next two lines should be commented out if you wish to load this document
    # in Cadcorp SIS from behind the University of Reading firewall
    output.write(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
    output.write(" xsi:schemaLocation=\"http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd\"")
    output.write(">")
    
    output.write("<Service>")
    output.write("<Name>WMS</Name>")
    output.write("<Title>%s</Title>" % config.title)
    output.write("<Abstract>%s</Abstract>" % config.abstract)
    output.write("<KeywordList>")
    for keyword in config.keywords:
        output.write("<Keyword>%s</Keyword>" % keyword)
    output.write("</KeywordList>")
    output.write("<OnlineResource xlink:type=\"simple\" xlink:href=\"%s\"/>" % config.url)

    output.write("<ContactInformation>")
    output.write("<ContactPersonPrimary>")
    output.write("<ContactPerson>%s</ContactPerson>" % config.contactName)
    output.write("<ContactOrganization>%s</ContactOrganization>" % config.contactOrg)
    output.write("</ContactPersonPrimary>")
    output.write("<ContactVoiceTelephone>%s</ContactVoiceTelephone>" % config.contactTel)
    output.write("<ContactElectronicMailAddress>%s</ContactElectronicMailAddress>" % config.contactEmail)
    output.write("</ContactInformation>")

    output.write("<Fees>none</Fees>")
    output.write("<AccessConstraints>none</AccessConstraints>")
    output.write("<LayerLimit>%d</LayerLimit>" % getmap.getLayerLimit())
    output.write("<MaxWidth>%d</MaxWidth>" % config.maxImageWidth)
    output.write("<MaxHeight>%d</MaxHeight>" % config.maxImageHeight)
    output.write("</Service>")
    
    output.write("<Capability>")
    output.write("<Request>")
    output.write("<GetCapabilities>")
    output.write("<Format>text/xml</Format>")
    url = "http://%s%s?" % (req.server.server_hostname, req.unparsed_uri.split("?")[0])
    output.write("<DCPType><HTTP><Get><OnlineResource xlink:type=\"simple\" xlink:href=\"" +
        url + "\"/></Get></HTTP></DCPType>")
    output.write("</GetCapabilities>")
    output.write("<GetMap>")
    for format in getmap.getSupportedImageFormats():
        output.write("<Format>%s</Format>" % format)
    output.write("<DCPType><HTTP><Get><OnlineResource xlink:type=\"simple\" xlink:href=\"" +
        url + "\"/></Get></HTTP></DCPType>")
    output.write("</GetMap>")
    if config.allowFeatureInfo:
        output.write("<GetFeatureInfo>")
        for format in getfeatureinfo.getSupportedFormats():
            output.write("<Format>%s</Format>" % format)
        output.write("<DCPType><HTTP><Get><OnlineResource xlink:type=\"simple\" xlink:href=\"" +
            url + "\"/></Get></HTTP></DCPType>")
        output.write("</GetFeatureInfo>")
    output.write("</Request>")
    # TODO: support more exception types
    output.write("<Exception>")
    for ex_format in getmap.getSupportedExceptionFormats():
        output.write("<Format>%s</Format>" % ex_format)
    output.write("</Exception>")

    # Write the top-level container layer
    output.write("<Layer>")
    output.write("<Title>%s</Title>" % config.title)
    # TODO: add styles
    for crs in grids.getSupportedCRSs().keys():
        output.write("<CRS>" + crs + "</CRS>")
    
    # Now for the dataset layers
    datasets = config.datasets
    for dsid in datasets.keys():
        # Write a container layer for this dataset. Container layers
        # do not have a Name
        output.write("<Layer>")
        output.write("<Title>%s</Title>" % datasets[dsid].title)
        # Now write the displayable data layers
        vars = datareader.getVariableMetadata(datasets[dsid].location)
        for vid in vars.keys():
            output.write("<Layer")
            if config.allowFeatureInfo and datasets[dsid].queryable:
                output.write(" queryable=\"1\"")
            output.write(">")
            output.write("<Name>%s%s%s</Name>" % (dsid, wmsUtils.getLayerSeparator(), vid))
            output.write("<Title>%s</Title>" % vars[vid].title)
            output.write("<Abstract>%s</Abstract>" % vars[vid].abstract)

            # Set the bounding box
            minLon, minLat, maxLon, maxLat = vars[vid].bbox
            output.write("<EX_GeographicBoundingBox>")
            output.write("<westBoundLongitude>%s</westBoundLongitude>" % str(minLon))
            output.write("<eastBoundLongitude>%s</eastBoundLongitude>" % str(maxLon))
            output.write("<southBoundLatitude>%s</southBoundLatitude>" % str(minLat))
            output.write("<northBoundLatitude>%s</northBoundLatitude>" % str(maxLat))
            output.write("</EX_GeographicBoundingBox>")
            output.write("<BoundingBox CRS=\"CRS:84\" ")
            output.write("minx=\"%f\" maxx=\"%f\" miny=\"%f\" maxy=\"%f\"/>"
                % (minLon, maxLon, minLat, maxLat))

            # Set the level dimension
            if vars[vid].zvalues is not None:
                output.write("<Dimension name=\"elevation\" units=\"%s\"" 
                    % vars[vid].zunits)
                # Use the first value in the array as the default
                # If the default value is removed, you also need to edit
                # the data reading code (e.g. DataReader.java) to
                # disallow default z values
                output.write(" default=\"%s\">" % vars[vid].zvalues[0])
                firstTime = 1
                for z in vars[vid].zvalues:
                    if firstTime:
                        firstTime = 0
                    else:
                        output.write(",")
                    output.write(str(z))
                output.write("</Dimension>")

            # Set the time dimension
            if vars[vid].tvalues is not None:
                output.write("<Dimension name=\"time\" units=\"ISO8601\">")
                # If we change this to support the "current" attribute
                # we must also change the data reading code
                firstTime = 1
                for t in vars[vid].tvalues:
                    if firstTime:
                        firstTime = 0
                    else:
                        output.write(",")
                    output.write(iso8601.tostring(t))
                output.write("</Dimension>")

            output.write("</Layer>") # end of variable Layer
        output.write("</Layer>") # end of dataset layer
    
    output.write("</Layer>") # end of top-level container layer
    
    output.write("</Capability>")
    output.write("</WMS_Capabilities>")

    req.content_type="text/xml"
    req.write(output.getvalue())
    output.close() # Free the buffer
    return
Exemple #10
0
 def set_last_sync_stop(self, profile, val=None, sync=True):
     if not val:
         val = iso8601.tostring(time.time())
     return self._set_profile_prop(profile, 'last_sync_stop', val, sync)
Exemple #11
0
 def get_curr_time(self):
     return iso8601.tostring(time.time())
Exemple #12
0
 def set_last_sync_stop (self, profile, val=None, sync=True):
     if not val:
         val = iso8601.tostring(time.time())
     return self._set_profile_prop(profile, 'last_sync_stop', val, sync)
Exemple #13
0
 def get_curr_time (self):
     return iso8601.tostring(time.time())
Exemple #14
0
    def prep_sync_lists (self, destid, sl, synct_sto=None, cnt=0):
        """See the documentation in folder.Folder"""

        pname = sl.get_pname()
        conf  = self.get_config()
        pdb1id = conf.get_profile_db1(pname)
        oldi  = conf.get_itemids(pname)
        stag  = conf.make_sync_label(pname, destid)

        logging.info('Querying MAPI for status of Contact Entries')

        ## Sort the DBIds so dest1 has the 'lower' ID
        dest1 = self.get_db().get_dbid()
        if dest1 > destid:
            dest2 = dest1
            dest1 = destid
        else:
            dest2 = destid

        ctable = self.get_contents()
        stp = self.get_proptags().sync_tags[stag]

        cols = (mt.PR_ENTRYID, mt.PR_LAST_MODIFICATION_TIME,
                mt.PR_DISPLAY_NAME, stp)
        ctable.SetColumns(cols, 0)

        i   = 0

        synct_str = self.get_config().get_last_sync_start(pname)
        if not synct_sto:
            synct_sto = self.get_config().get_last_sync_stop(pname)
        synct     = iso8601.parse(synct_sto)
        logging.debug('Last Start iso str : %s', synct_str)
        logging.debug('Last Stop  iso str : %s', synct_sto)
        logging.debug('Current Time       : %s', iso8601.tostring(time.time()))

        logging.info('Data obtained from MAPI. Processing...')

        newi = {}
        while True:
            rows = ctable.QueryRows(1, 0)
            #if this is the last row then stop
            if len(rows) != 1:
                break

            ((entryid_tag, entryid), (tt, modt),
             (name_tag, name), (gid_tag, gid)) = rows[0]
            b64_entryid = base64.b64encode(entryid)

            newi.update({b64_entryid : gid})

            if mt.PROP_TYPE(gid_tag) == mt.PT_ERROR:
                # Was not synced for whatever reason.
                logging.debug('New      Outlook Contact: %20s %s', 
                              name, b64_entryid)
                sl.add_new(b64_entryid)
            else:
                if mt.PROP_TYPE(tt) == mt.PT_ERROR:
                    logging.debug('Impossible! Entry has no timestamp. i = %d', i)
                else:
                    if utils.utc_time_to_local_ts(modt) <= synct:
                        sl.add_unmod(b64_entryid)
                    else:
                        logging.debug('Modified Outlook Contact: %20s %s', 
                                      name, b64_entryid)
                        sl.add_mod(b64_entryid, gid)

            i += 1
            if cnt != 0 and i >= cnt:
                break

        ctable.SetColumns(self.get_def_cols(), 0)

        kss = newi.keys()
        for x, y in oldi.iteritems():
            if not x in kss and not y in kss:
                logging.debug('Deleted Outlook Contact: %s:%s', x, y)
                if pdb1id == self.get_dbid():
                    sl.add_del(x, y)
                else:
                    sl.add_del(y,x)
Exemple #15
0
def getCalendar(config, dataset, varID, dateTime):
    """ returns an HTML calendar for the given dataset and variable.
        dateTime is a string in ISO 8601 format with the required
        'focus time' """
    datasets = config.datasets
    # Get an array of time axis values in seconds since the epoch
    tValues = datareader.getVariableMetadata(datasets[dataset].location)[varID].tvalues
    # TODO: is this the right thing to do here?
    if tValues is None:
        return ""
    str = StringIO()
    prettyDateFormat = "%d %b %Y"

    # Find the closest time step to the given dateTime value
    # TODO: binary search would be more efficient
    reqTime = iso8601.parse(dateTime) # Gives seconds since the epoch
    diff = 1e20
    for i in xrange(len(tValues)):
        testDiff = math.fabs(tValues[i] - reqTime)
        if testDiff < diff:
            # Axis is monotonic so we should move closer and closer
            # to the nearest value
            diff = testDiff
            nearestIndex = i
        elif i > 0:
            # We've moved past the closest date
            break
    
    str.write("<root>")
    str.write("<nearestValue>%s</nearestValue>" % iso8601.tostring(tValues[nearestIndex]))
    str.write("<prettyNearestValue>%s</prettyNearestValue>" % time.strftime(prettyDateFormat, time.gmtime(tValues[nearestIndex])))
    str.write("<nearestIndex>%d</nearestIndex>" % nearestIndex)

    # create a struct_time tuple with zero timezone offset (i.e. GMT)
    nearesttime = time.gmtime(tValues[nearestIndex])

    # Now print out the calendar in HTML
    str.write("<calendar>")
    str.write("<table><tbody>")
    # Add the navigation buttons at the top of the month view
    str.write("<tr>")
    str.write("<td><a href=\"#\" onclick=\"javascript:setCalendar('%s','%s','%s'); return false\">&lt;&lt;</a></td>" % (dataset, varID, _getYearBefore(nearesttime)))
    str.write("<td><a href=\"#\" onclick=\"javascript:setCalendar('%s','%s','%s'); return false\">&lt;</a></td>" % (dataset, varID, _getMonthBefore(nearesttime)))
    str.write("<td colspan=\"3\">%s</td>" % _getHeading(nearesttime))
    str.write("<td><a href=\"#\" onclick=\"javascript:setCalendar('%s','%s','%s'); return false\">&gt;</a></td>" % (dataset, varID, _getMonthAfter(nearesttime)))
    str.write("<td><a href=\"#\" onclick=\"javascript:setCalendar('%s','%s','%s'); return false\">&gt;&gt;</a></td>" % (dataset, varID, _getYearAfter(nearesttime)))
    str.write("</tr>")
    # Add the day-of-week headings
    str.write("<tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>")
    # Add the calendar body
    tValIndex = 0 # index in tvalues array
    for week in calendar.monthcalendar(nearesttime[0], nearesttime[1]):
        str.write("<tr>")
        for day in week:
            if day > 0:
                # Search through the t axis and find out whether we have
                # any data for this particular day
                found = 0
                calendarDay = (nearesttime[0], nearesttime[1], day, 0, 0, 0, 0, 0, 0)
                while not found and tValIndex < len(tValues):
                    axisDay = time.gmtime(tValues[tValIndex])
                    res = _compareDays(axisDay, calendarDay)
                    if res == 0:
                        found = 1 # Found data on this day
                    elif res < 0:
                        tValIndex = tValIndex + 1 # Date on axis is before target day
                    else:
                        break # Date on axis is after target day: no point searching further
                if found:
                    tValue = iso8601.tostring(tValues[tValIndex])
                    prettyTValue = time.strftime(prettyDateFormat, axisDay)
                    str.write("<td id=\"t%d\"><a href=\"#\" onclick=\"javascript:getTimesteps('%s','%s','%d','%s','%s'); return false\">%d</a></td>" % (tValIndex, dataset, varID, tValIndex, tValue, prettyTValue, day))
                else:
                    str.write("<td>%d</td>" % day)
            else:
                str.write("<td></td>")
        str.write("</tr>")

    str.write("</tbody></table>")
    str.write("</calendar>")
    str.write("</root>")

    s = str.getvalue()
    str.close()
    return s
Exemple #16
0
    def prep_sync_lists(self, destid, sl, synct_sto=None, cnt=0):
        """See the documentation in folder.Folder"""

        pname = sl.get_pname()
        conf = self.get_config()
        pdb1id = conf.get_profile_db1(pname)
        oldi = conf.get_itemids(pname)
        stag = conf.make_sync_label(pname, destid)

        logging.info('Querying MAPI for status of Contact Entries')

        ## Sort the DBIds so dest1 has the 'lower' ID
        dest1 = self.get_db().get_dbid()
        if dest1 > destid:
            dest2 = dest1
            dest1 = destid
        else:
            dest2 = destid

        ctable = self.get_contents()
        stp = self.get_proptags().sync_tags[stag]

        cols = (mt.PR_ENTRYID, mt.PR_LAST_MODIFICATION_TIME,
                mt.PR_DISPLAY_NAME, stp)
        ctable.SetColumns(cols, 0)

        i = 0

        synct_str = self.get_config().get_last_sync_start(pname)
        if not synct_sto:
            synct_sto = self.get_config().get_last_sync_stop(pname)
        synct = iso8601.parse(synct_sto)
        logging.debug('Last Start iso str : %s', synct_str)
        logging.debug('Last Stop  iso str : %s', synct_sto)
        logging.debug('Current Time       : %s', iso8601.tostring(time.time()))

        logging.info('Data obtained from MAPI. Processing...')

        newi = {}
        while True:
            rows = ctable.QueryRows(1, 0)
            #if this is the last row then stop
            if len(rows) != 1:
                break

            ((entryid_tag, entryid), (tt, modt), (name_tag, name),
             (gid_tag, gid)) = rows[0]
            b64_entryid = base64.b64encode(entryid)

            newi.update({b64_entryid: gid})

            if mt.PROP_TYPE(gid_tag) == mt.PT_ERROR:
                # Was not synced for whatever reason.
                logging.debug('New      Outlook Contact: %20s %s', name,
                              b64_entryid)
                sl.add_new(b64_entryid)
            else:
                if mt.PROP_TYPE(tt) == mt.PT_ERROR:
                    logging.debug('Impossible! Entry has no timestamp. i = %d',
                                  i)
                else:
                    if utils.utc_time_to_local_ts(modt) <= synct:
                        sl.add_unmod(b64_entryid)
                    else:
                        logging.debug('Modified Outlook Contact: %20s %s',
                                      name, b64_entryid)
                        sl.add_mod(b64_entryid, gid)

            i += 1
            if cnt != 0 and i >= cnt:
                break

        ctable.SetColumns(self.get_def_cols(), 0)

        kss = newi.keys()
        for x, y in oldi.iteritems():
            if not x in kss and not y in kss:
                logging.debug('Deleted Outlook Contact: %s:%s', x, y)
                if pdb1id == self.get_dbid():
                    sl.add_del(x, y)
                else:
                    sl.add_del(y, x)
Exemple #17
0
def dt_to_string(dt):
    """Convert a datetime object to an ISO8601 string."""
    return iso8601.tostring(time.mktime(dt.timetuple()))
Exemple #18
0
    def prep_sync_lists (self, destid, sl, synct_sto=None, cnt=0):
        """See the documentation in folder.Folder"""

        pname = sl.get_pname()
        stag  = self.get_config().make_sync_label(pname, destid)

        logging.info('Querying MAPI for status of Contact Entries')

        ## Sort the DBIds so dest1 has the 'lower' ID
        dest1 = self.get_db().get_dbid()
        if dest1 > destid:
            dest2 = dest1
            dest1 = destid
        else:
            dest2 = destid

        ctable = self.get_contents()
        ## FIXME: This needs to be fixed. The ID will be different based on
        ## the actual remote database, of course.
        stp = self.get_proptags().sync_tags[stag]

        cols = (mt.PR_ENTRYID, mt.PR_LAST_MODIFICATION_TIME,
                mt.PR_DISPLAY_NAME, stp)
        ctable.SetColumns(cols, 0)

        i   = 0

        pname = sl.get_pname()
        synct_str = self.get_config().get_last_sync_start(pname)
        if not synct_sto:
            synct_sto = self.get_config().get_last_sync_stop(pname)
        synct     = iso8601.parse(synct_sto)
        logging.debug('Last Start iso str : %s', synct_str)
        logging.debug('Last Stop  iso str : %s', synct_sto)
        logging.debug('Current Time       : %s', iso8601.tostring(time.time()))

        logging.info('Data obtained from MAPI. Processing...')

        while True:
            rows = ctable.QueryRows(1, 0)
            #if this is the last row then stop
            if len(rows) != 1:
                break

            ((entryid_tag, entryid), (tt, modt),
             (name_tag, name), (gid_tag, gid)) = rows[0]
            b64_entryid = base64.b64encode(entryid)

            sl.add_entry(b64_entryid, gid)

            if mt.PROP_TYPE(gid_tag) == mt.PT_ERROR:
                # Was not synced for whatever reason.
                sl.add_new(b64_entryid)
            else:
                if mt.PROP_TYPE(tt) == mt.PT_ERROR:
                    logging.debug('Impossible! Entry has no timestamp. i = %d', i)
                else:
                    if utils.utc_time_to_local_ts(modt) <= synct:
                        sl.add_unmod(b64_entryid)
                    else:
                        sl.add_mod(b64_entryid, gid)

            i += 1
            if cnt != 0 and i >= cnt:
                break

        ctable.SetColumns(self.get_def_cols(), 0)
Exemple #19
0
def _getYearAfter(date):
    """ Returns an ISO8601-formatted date that is exactly one year later than
        the given date """
    # Get the tuple of year, month, day etc
    newDate = tuple([date[0] + 1] + list(date[1:]))
    return iso8601.tostring(time.mktime(newDate))