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
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))
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()))
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")
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)
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)
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
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
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)
def get_curr_time(self): return iso8601.tostring(time.time())
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)
def get_curr_time (self): return iso8601.tostring(time.time())
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)
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\"><<</a></td>" % (dataset, varID, _getYearBefore(nearesttime))) str.write("<td><a href=\"#\" onclick=\"javascript:setCalendar('%s','%s','%s'); return false\"><</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\">></a></td>" % (dataset, varID, _getMonthAfter(nearesttime))) str.write("<td><a href=\"#\" onclick=\"javascript:setCalendar('%s','%s','%s'); return false\">>></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
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)
def dt_to_string(dt): """Convert a datetime object to an ISO8601 string.""" return iso8601.tostring(time.mktime(dt.timetuple()))
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)
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))