def getSession(self): store = Store.of(self) if store is None: return None if len(self.UserName) == 0 or len(self.EMail) == 0 or len( self.PasswordHash) == 0: return None # delete old sessions old = store.find(APISession, APISession.UserID == self.ID).any() if old is not None: old.delete() # generate a new session id sid = unicode(sha256(unicode(int(TimeUtils.now()))).hexdigest()) while store.find(APISession, APISession.Key == sid).any() is not None: sid = unicode( sha256( unicode(int(TimeUtils.now())) + unicode(rnd.randint(0, 655535))).hexdigest()) # create a new session session = APISession(sid, self.ID, int(TimeUtils.now() + 86400)) store.add(session) for cap in self.Capabilities: session.Capabilities.add(cap) return session
def getStationFrequencies(self, station, notModifiedCheck = None, head = False): global UPCOMING, PAST, ONAIR broadcasts = self.store.find(Broadcast, Broadcast.StationID == station.ID) lastModified = max( broadcasts.max(Broadcast.Modified), station.BroadcastRemoved ) if station.Schedule is not None: scheduleLeafs = self.store.find(ScheduleLeaf, ScheduleLeaf.StationID == station.ID) lastModified = lastModified if station.Schedule.Modified < lastModified else station.Schedule.Modified if head: return (lastModified, None) if notModifiedCheck is not None: notModifiedCheck(lastModified) if station.Schedule is None: now = TimeUtils.now() frequencies = self.store.find( (Max(Broadcast.BroadcastEnd), Min(Broadcast.BroadcastStart), Broadcast.BroadcastStart > now, BroadcastFrequency.Frequency, Modulation.Name), BroadcastFrequency.ModulationID == Modulation.ID, BroadcastFrequency.BroadcastID == Broadcast.ID, Broadcast.StationID == station.ID) frequencies.group_by(Or(Func("ISNULL", Broadcast.BroadcastEnd), And(Broadcast.BroadcastEnd >= now, Broadcast.BroadcastStart <= now)), Broadcast.BroadcastStart > now, BroadcastFrequency.Frequency, Modulation.Name) return (lastModified, ((freq, modulation, UPCOMING if isUpcoming == 1 else (ONAIR if lastUse is None else PAST), nextUse if isUpcoming else lastUse) for (lastUse, nextUse, isUpcoming, freq, modulation) in frequencies))
def getUpcomingBroadcasts(self, station, all, update, timeLimit, maxTimeRange, limiter = None, notModifiedCheck = None, head = False): now = TimeUtils.now() where = And(Or(Broadcast.BroadcastEnd > now, Broadcast.BroadcastEnd == None), (Broadcast.BroadcastStart < (now + timeLimit))) if not all: where = And(where, Broadcast.Type == u"data") if station is not None: where = And(where, Broadcast.StationID == stationId) broadcasts = self.store.find(Broadcast, where) lastModified = max( broadcasts.max(Broadcast.Modified), station.BroadcastRemoved if station is not None else None, station.Schedule.Modified if (station is not None and station.Schedule is not None) else None ) if head: return (lastModified, None, None, None) if notModifiedCheck is not None: notModifiedCheck(lastModified) if update: untilDate = datetime.fromtimestamp(now) untilDate += timedelta(seconds=timeLimit) untilDate = self.normalizeDate(untilDate) until = TimeUtils.toTimestamp(untilDate) if station is None: validUntil = self.scheduleMaintainer.updateSchedules(until, maxTimeRange) else: validUntil = self.scheduleMaintainer.updateSchedule(station, until, maxTimeRange) # trans.set_header_value("Expires", self.model.formatHTTPTimestamp(validUntil)) return (lastModified, broadcasts if limiter is None else limiter(broadcasts), validUntil >= until, validUntil)
def getSession(self): store = Store.of(self) if store is None: return None if len(self.UserName) == 0 or len(self.EMail) == 0 or len(self.PasswordHash) == 0: return None # delete old sessions old = store.find(APISession, APISession.UserID == self.ID).any() if old is not None: old.delete() # generate a new session id sid = unicode(sha256(unicode(int(TimeUtils.now()))).hexdigest()) while store.find(APISession, APISession.Key == sid).any() is not None: sid = unicode(sha256(unicode(int(TimeUtils.now()))+unicode(rnd.randint(0, 655535))).hexdigest()) # create a new session session = APISession(sid, self.ID, int(TimeUtils.now() + 86400)) store.add(session) for cap in self.Capabilities: session.Capabilities.add(cap) return session
def updateSchedule(self, station, until, limit=None): now = TimeUtils.now() if station.Schedule is None: return until if until is None or (until - now) > limits.schedule.maxLookahead: until = now + limits.schedule.maxLookahead if station.ScheduleUpToDateUntil is None: start = now else: start = station.ScheduleUpToDateUntil if until <= start: return start if limit is not None and (until - start) > limit: until = start + limit self._rebuildStationSchedule(station, start, until) self.store.flush() return until
def getUpcomingBroadcasts(self, station, all, update, timeLimit, maxTimeRange, limiter=None, notModifiedCheck=None, head=False): now = TimeUtils.now() where = And( Or(Broadcast.BroadcastEnd > now, Broadcast.BroadcastEnd == None), (Broadcast.BroadcastStart < (now + timeLimit))) if not all: where = And(where, Broadcast.Type == u"data") if station is not None: where = And(where, Broadcast.StationID == stationId) broadcasts = self.store.find(Broadcast, where) lastModified = max( broadcasts.max(Broadcast.Modified), station.BroadcastRemoved if station is not None else None, station.Schedule.Modified if (station is not None and station.Schedule is not None) else None) if head: return (lastModified, None, None, None) if notModifiedCheck is not None: notModifiedCheck(lastModified) if update: untilDate = datetime.fromtimestamp(now) untilDate += timedelta(seconds=timeLimit) untilDate = self.normalizeDate(untilDate) until = TimeUtils.toTimestamp(untilDate) if station is None: validUntil = self.scheduleMaintainer.updateSchedules( until, maxTimeRange) else: validUntil = self.scheduleMaintainer.updateSchedule( station, until, maxTimeRange) # trans.set_header_value("Expires", self.model.formatHTTPTimestamp(validUntil)) return (lastModified, broadcasts if limiter is None else limiter(broadcasts), validUntil >= until, validUntil)
def updateSchedule(self, station, until, limit = None): now = TimeUtils.now() if station.Schedule is None: return until if until is None or (until - now) > limits.schedule.maxLookahead: until = now + limits.schedule.maxLookahead if station.ScheduleUpToDateUntil is None: start = now else: start = station.ScheduleUpToDateUntil if until <= start: return start if limit is not None and (until - start) > limit: until = start + limit self._rebuildStationSchedule(station, start, until) self.store.flush() return until
def updateSchedules(self, until, limit = None): now = TimeUtils.now() if until is None or (until - now) > limits.schedule.maxLookahead: until = now + limits.schedule.maxLookahead validUntil = until if limit is None: limit = until for station in self.store.find(Station, Station.Schedule != None, Or(Station.ScheduleUpToDateUntil < until, Station.ScheduleUpToDateUntil == None)): start = now if station.ScheduleUpToDateUntil is not None: start = station.ScheduleUpToDateUntil if until <= start: continue if (until - start) > limit: self._rebuildStationSchedule(station, start, start+limit) validUntil = min(validUntil, start+limit) else: self._rebuildStationSchedule(station, start, until) self.store.flush() return validUntil
def getStationFrequencies(self, station, notModifiedCheck=None, head=False): global UPCOMING, PAST, ONAIR broadcasts = self.store.find(Broadcast, Broadcast.StationID == station.ID) lastModified = max(broadcasts.max(Broadcast.Modified), station.BroadcastRemoved) if station.Schedule is not None: scheduleLeafs = self.store.find( ScheduleLeaf, ScheduleLeaf.StationID == station.ID) lastModified = lastModified if station.Schedule.Modified < lastModified else station.Schedule.Modified if head: return (lastModified, None) if notModifiedCheck is not None: notModifiedCheck(lastModified) if station.Schedule is None: now = TimeUtils.now() frequencies = self.store.find( (Max(Broadcast.BroadcastEnd), Min( Broadcast.BroadcastStart), Broadcast.BroadcastStart > now, BroadcastFrequency.Frequency, Modulation.Name), BroadcastFrequency.ModulationID == Modulation.ID, BroadcastFrequency.BroadcastID == Broadcast.ID, Broadcast.StationID == station.ID) frequencies.group_by( Or( Func("ISNULL", Broadcast.BroadcastEnd), And(Broadcast.BroadcastEnd >= now, Broadcast.BroadcastStart <= now)), Broadcast.BroadcastStart > now, BroadcastFrequency.Frequency, Modulation.Name) return (lastModified, ((freq, modulation, UPCOMING if isUpcoming == 1 else (ONAIR if lastUse is None else PAST), nextUse if isUpcoming else lastUse) for (lastUse, nextUse, isUpcoming, freq, modulation) in frequencies))
def updateSchedules(self, until, limit=None): now = TimeUtils.now() if until is None or (until - now) > limits.schedule.maxLookahead: until = now + limits.schedule.maxLookahead validUntil = until if limit is None: limit = until for station in self.store.find( Station, Station.Schedule != None, Or(Station.ScheduleUpToDateUntil < until, Station.ScheduleUpToDateUntil == None), ): start = now if station.ScheduleUpToDateUntil is not None: start = station.ScheduleUpToDateUntil if until <= start: continue if (until - start) > limit: self._rebuildStationSchedule(station, start, start + limit) validUntil = min(validUntil, start + limit) else: self._rebuildStationSchedule(station, start, until) self.store.flush() return validUntil
def handleException(self, trans, exceptionType, exception, tb): plainTextMessage = u"""On request: {0} {1} the following exception occured at {2}: """.format(trans.get_request_method(), trans.get_path(), TimeUtils.nowDate().isoformat()) plainTextMessage += self.generatePlainTextMessage( trans, exceptionType, exception, tb) print(plainTextMessage.encode("utf-8")) if "mail-to" in errors: try: mailConfig = errors["mail-to"] subject = mailConfig["subject"].format(exceptionType.__name__, unicode(exception)) to = mailConfig["to"] sender = mailConfig["sender"] smtp = mailConfig["smtp"] mail = MIMEText(plainTextMessage.encode("utf-8"), _charset="utf-8") mail["Subject"] = subject mail["To"] = ",".join(to) mail["From"] = sender mail["Date"] = self.model.formatHTTPTimestamp(TimeUtils.now()) host = smtp["host"] port = int(smtp.get("port", 25)) user = smtp.get("user", None) password = smtp.get("password", None) secure = smtp.get("secure", None) if not secure in ["starttls", "ssl"]: raise ValueError( "Invalid value for secure: {0}".format(secure)) if secure == "ssl": conn = smtplib.SMTP_SSL(host, port) else: conn = smtplib.SMTP(host, port) if secure == "starttls": conn.starttls() if user is not None and password is not None: conn.login(user, password) conn.sendmail(mail["From"], mail["To"], mail.as_string()) conn.quit() except Exception as e: print("Could not send exception mail: {0}".format(e)) trans.rollback() trans.set_response_code(500) self.out = trans.get_response_stream() trans.set_content_type(ContentType("text/html", "utf-8")) s = u""" <html> <head> <title>Priyom.org internal API error</title> <link rel="stylesheet" type="text/css" href="{0}"/> </head> <body> <h1>Internal API error</h1>""".format( application.get("urlroot", u"") + u"/css/error.css") if self.show: s += u""" <h2>Error information</h2> <dl class="exc-info"> <dt>Exception class:</dt> <dd>{1}</dd> <dt>Message:</dt> <dd>{2}</dd> </dl> <h2>Stacktrace</h2> <p>(most recent call last)</p> <ul>{0}</ul>""".format( u"\n".join(( u"""<li><div class="tb-item-head">File "<span class="tb-file">{0}</span>", line <span class="tb-lineno">{1:d}</span>, in <span class="tb-func">{2}</span></div><div class="tb-item-code">{3}</div>""" .format( escape(os.path.relpath(filename, application["root"])), lineno, escape(funcname), escape(text)) for (filename, lineno, funcname, text) in traceback.extract_tb(tb))), escape(unicode(exceptionType)), escape(unicode(exception)).replace("\n", "<br/>")) else: s += u""" <p>An internal error has occured. Please report this to <a href="mailto:{0}">{1}</a></p>""".format( admin["mail"], admin["name"]) s += u""" </body> </html>""" print >> self.out, s.encode("utf-8")
def broadcastRemoved(self): self.BroadcastRemoved = int(TimeUtils.now())
def isValid(self): store = Store.of(self) return (store is not None) and (len(self.Key) > 0) and (self.Expires > TimeUtils.now())
def transmissionRemoved(self): self.TransmissionRemoved = int(TimeUtils.now())
def handleException(self, trans, exceptionType, exception, tb): plainTextMessage = u"""On request: {0} {1} the following exception occured at {2}: """.format(trans.get_request_method(), trans.get_path(), TimeUtils.nowDate().isoformat()) plainTextMessage += self.generatePlainTextMessage(trans, exceptionType, exception, tb) print(plainTextMessage.encode("utf-8")) if "mail-to" in errors: try: mailConfig = errors["mail-to"] subject = mailConfig["subject"].format(exceptionType.__name__, unicode(exception)) to = mailConfig["to"] sender = mailConfig["sender"] smtp = mailConfig["smtp"] mail = MIMEText(plainTextMessage.encode("utf-8"), _charset="utf-8") mail["Subject"] = subject mail["To"] = ",".join(to) mail["From"] = sender mail["Date"] = self.model.formatHTTPTimestamp(TimeUtils.now()) host = smtp["host"] port = int(smtp.get("port", 25)) user = smtp.get("user", None) password = smtp.get("password", None) secure = smtp.get("secure", None) if not secure in ["starttls", "ssl"]: raise ValueError("Invalid value for secure: {0}".format(secure)) if secure == "ssl": conn = smtplib.SMTP_SSL(host, port) else: conn = smtplib.SMTP(host, port) if secure == "starttls": conn.starttls() if user is not None and password is not None: conn.login(user, password) conn.sendmail(mail["From"], mail["To"], mail.as_string()) conn.quit() except Exception as e : print("Could not send exception mail: {0}".format(e)) trans.rollback() trans.set_response_code(500) self.out = trans.get_response_stream() trans.set_content_type(ContentType("text/html", "utf-8")) s = u""" <html> <head> <title>Priyom.org internal API error</title> <link rel="stylesheet" type="text/css" href="{0}"/> </head> <body> <h1>Internal API error</h1>""".format(application.get("urlroot", u"") + u"/css/error.css") if self.show: s += u""" <h2>Error information</h2> <dl class="exc-info"> <dt>Exception class:</dt> <dd>{1}</dd> <dt>Message:</dt> <dd>{2}</dd> </dl> <h2>Stacktrace</h2> <p>(most recent call last)</p> <ul>{0}</ul>""".format( u"\n".join((u"""<li><div class="tb-item-head">File "<span class="tb-file">{0}</span>", line <span class="tb-lineno">{1:d}</span>, in <span class="tb-func">{2}</span></div><div class="tb-item-code">{3}</div>""".format(escape(os.path.relpath(filename, application["root"])), lineno, escape(funcname), escape(text)) for (filename, lineno, funcname, text) in traceback.extract_tb(tb))), escape(unicode(exceptionType)), escape(unicode(exception)).replace("\n", "<br/>") ) else: s += u""" <p>An internal error has occured. Please report this to <a href="mailto:{0}">{1}</a></p>""".format(admin["mail"], admin["name"]) s += u""" </body> </html>""" print >>self.out, s.encode("utf-8")