示例#1
0
class CloseBroadcastsAPI(API):
    title = u"getCloseBroadcasts"
    shortDescription = u"Find broadcasts close to a given timestamp"
    
    docArgs = [
        Argument(u"stationId", u"station ID", u"id of the station at which to search for broadcasts", metavar=u"stationid"),
        Argument(u"time", u"unix timestamp", u"center of the time area which to take into account", metavar=u"timestamp"),
        Argument(u"jitter", u"seconds", u"amount of seconds to look around the given timestamp. defaults to 600 seconds", metavar=u"seconds", optional=True)
    ]
    docCallSyntax = CallSyntax(docArgs, u"?{0}&{1}&{2}")
    
    def handle(self, trans):
        stationId = self.getQueryInt("stationId", "int; id of the station")
        time = self.getQueryInt("time", "int; unix timestamp at which to look")
        jitter = self.getQueryIntDefault("jitter", 600, "int; jitter in seconds")
        if jitter < 0 or jitter > 600:
            self.parameterError("jitter", "jitter %d out of bounds (0..600)" % (jitter))
            
        
        lastModified, broadcasts = self.priyomInterface.getCloseBroadcasts(stationId, time, jitter, notModifiedCheck=self.autoNotModified, head=self.head)
        trans.set_content_type(ContentType("application/xml", self.encoding))
        trans.set_header_value("Last-Modified", self.model.formatHTTPTimestamp(lastModified))
        if self.head:
            return
        
        self.model.exportListToFile(self.out, broadcasts, Broadcast, encoding=self.encoding)
class TransmissionsByMonthAPI(API):
    title = u"getTransmissionsByMonth"
    shortDescription = u"list the transmissions of a given calendar month"

    docArgs = [
        Argument(u"stationId",
                 u"station id",
                 u"select the station at which to look",
                 metavar="stationid"),
        Argument(u"year", u"integer year", u"year to look at", metavar="year"),
        Argument(u"month",
                 u"integer month (1-12)",
                 u"month of year to look at",
                 metavar="month")
    ]
    docCallSyntax = CallSyntax(docArgs, u"?{0}&{1}&{2}")

    def handle(self, trans):
        stationId = self.getQueryInt("stationId", "must be integer")
        year = self.getQueryInt("year", "must be integer")
        month = self.getQueryInt("month", "must be integer")
        if month < 1 or month > 12:
            self.parameterError("month",
                                "Month %d out of bounds (1..12)" % (month))
            return

        lastModified, transmissions = self.priyomInterface.getTransmissionsByMonth(
            stationId,
            year,
            month,
            limiter=None,
            notModifiedCheck=self.autoNotModified,
            head=self.head)

        trans.set_header_value(
            'Last-Modified',
            self.model.formatHTTPTimestamp(float(lastModified)))
        trans.set_content_type(ContentType('application/xml', self.encoding))
        if self.head:
            return

        self.model.exportListToFile(self.out,
                                    transmissions,
                                    Transmission,
                                    encoding=self.encoding,
                                    flags={"with-freqs"})
示例#3
0
class StationFrequenciesAPI(API):
    title = u"getStationFrequencies"
    shortDescription = u"get a list of frequencies the station uses"

    docArgs = [
        Argument(u"stationId",
                 u"station id",
                 u"select the station at which to look",
                 metavar="stationid")
    ]
    docCallSyntax = CallSyntax(docArgs, u"?{0}")

    def handle(self, trans):
        stationId = self.getQueryInt("stationId", "must be integer")
        station = self.store.get(Station, stationId)
        if station is None:
            self.parameterError("stationId", "Station does not exist")

        lastModified, frequencies = self.priyomInterface.getStationFrequencies(
            station, notModifiedCheck=self.autoNotModified, head=self.head)
        trans.set_content_type(ContentType("application/xml", self.encoding))
        trans.set_header_value("Last-Modified",
                               self.model.formatHTTPTimestamp(lastModified))
        if self.head:
            return

        doc = self.model.getExportTree("station-frequencies")
        rootNode = doc.getroot()

        for (freq, modulation, state, timestamp) in frequencies:
            node = XMLIntf.appendTextElement(rootNode,
                                             u"station-frequency",
                                             unicode(freq),
                                             attrib={
                                                 u"modulation": modulation,
                                                 u"state": state
                                             })
            if state != ONAIR:
                node.set(u"unix", unicode(timestamp))

        self.model.etreeToFile(self.out, doc, encoding=self.encoding)
class InstanciateSchedulesAPI(API):
    title = u"instanciateSchedules"
    shortDescription = u"instanciate schedules"

    docArgs = [
        Argument(u"stationId",
                 u"station ID",
                 u"Restrict the instanciation to a single station",
                 metavar="stationid",
                 optional=True),
    ]
    docCallSyntax = CallSyntax(docArgs, u"?{0}")
    docRequiredPrivilegues = u"instanciate"

    def __init__(self, model):
        super(InstanciateSchedulesAPI, self).__init__(model)
        self.allowedMethods = frozenset(("POST", "GET", "HEAD"))

    def handle(self, trans):
        stationId = self.getQueryIntDefault("stationId", None,
                                            "must be integer")

        trans.set_content_type(ContentType("text/plain", self.encoding))
        if self.head:
            return
        if trans.get_request_method() == "GET":
            print >> self.out, u"failed: Call this resource with POST to perform instanciation.".encode(
                self.encoding)
            return

        generatedUntil = 0
        if stationId is None:
            generatedUntil = self.priyomInterface.scheduleMaintainer.updateSchedules(
                None)
        else:
            generatedUntil = self.priyomInterface.scheduleMaintainer.updateSchedule(
                self.store.get(Station, stationId), None)

        print >> self.out, u"success: valid until {0}".format(
            datetime.fromtimestamp(generatedUntil).strftime(
                priyomdate)).encode(self.encoding)
示例#5
0
class TransmissionStatsAPI(API):
    title = u"getTransmissionStats"
    shortDescription = u"get the amount of transmissions grouped by calendar months"

    docArgs = [
        Argument(u"stationId",
                 u"station id",
                 u"select the station at which to look",
                 metavar="stationid")
    ]
    docCallSyntax = CallSyntax(docArgs, u"?{0}")

    def handle(self, trans):
        stationId = self.getQueryInt("stationId", "must be integer")

        lastModified, months = self.priyomInterface.getTransmissionStats(
            stationId, notModifiedCheck=self.autoNotModified, head=self.head)
        trans.set_content_type(ContentType("application/xml", self.encoding))
        trans.set_header_value(
            'Last-Modified',
            self.model.formatHTTPTimestamp(float(lastModified)))
        if self.head:
            return

        doc = self.model.getExportTree("transmission-stats")
        rootNode = doc.getroot()

        for month in months:
            XMLIntf.appendTextElement(rootNode,
                                      u"transmission-count",
                                      unicode(month[2]),
                                      attrib={
                                          u"year": unicode(month[0]),
                                          u"month": unicode(month[1])
                                      })

        self.model.etreeToFile(self.out, doc, encoding=self.encoding)
class DuplicatedTransmissionItemsAPI(API):
    title = u"getDuplicatedTransmissionItems"
    shortDescription = u"get a list of duplicated transmission items"
    
    docArgs = [
        Argument(u"stationId", u"station id", u"select the station at which to look", metavar="stationid"),
        Argument(u"tableId", u"class table id", u"select the transmission class table to look at", metavar="classtableid"),
        Argument(u"equalFields", u"comma separated list", u"transmission item fields to look at (all if omitted)", metavar="equalfields", optional=True),
        Argument(u"includeOtherStationsWithin", u"integer seconds", u"how many seconds transmissions of other stations with same contents may be away to be selected", metavar="seconds", optional=True)
    ]
    docCallSyntax = CallSyntax(docArgs, u"?{0}&{1}&{2}&{3}")

    
    def handle(self, trans):
        stationId = self.getQueryInt("stationId", "must be a station id")
        station = self.store.get(Station, stationId)
        if station is None:
            self.parameterError("stationId", "Station does not exist")
        
        tableId = self.getQueryInt("tableId", "must be a class table id")
        table = self.store.get(TransmissionTable, tableId)
        if table is None:
            self.parameterError("tableId", "Table does not exist")
            
        matchFields = [s for s in (item.lstrip().rstrip() for item in self.query.get("equalFields", u"").split(u",")) if len(s) > 0]
        if len(matchFields) == 0:
            matchFields = None
        else:
            for field in matchFields:
                if not hasattr(table, field):
                    self.parameterError("equalFields", "{0} is not a valid field for this table.".format(field))
                
        includeOtherStationsWithin = self.getQueryIntDefault("includeOtherStationsWithin", 86400, "must be integer seconds")
        
        
        lastModified, items = self.priyomInterface.getDuplicateTransmissions(table, station, matchFields, includeOtherStationsWithin, notModifiedCheck=self.autoNotModified, head=self.head)
        trans.set_content_type(ContentType("application/xml", self.encoding))
        trans.set_header_value("Last-Modified", self.model.formatHTTPTimestamp(float(lastModified)))
        if self.head:
            return
        
        doc = self.model.getExportTree("duplicated-transmissions")
        rootNode = doc.getroot()
        
        dupeDict = {}
        
        for bc1, tx1, txItem1, bc2, tx2, txItem2 in items:
            if matchFields is None:
                key = unicode(txItem1)
            else:
                key = u" ".join((getattr(txItem1, field) for field in matchFields))
            if key in dupeDict:
                rec = dupeDict[key]
                rec.add(bc1, tx1, txItem1)
                rec.add(bc2, tx2, txItem2)
                dupeDict[key] = rec
                continue
            
            node = XMLIntf.SubElement(rootNode, u"duplicated-transmission")
            #node.setAttribute("key", key)
            rec = DupeRecord(doc, node)
            rec.add(bc1, tx1, txItem1)
            rec.add(bc2, tx2, txItem2)
            dupeDict[key] = rec
        
        self.model.etreeToFile(self.out, doc, encoding=self.encoding)
示例#7
0
class SessionAPI(API):
    title = u"getSession"
    shortDescription = u"Login and get a session id"

    docArgs = [
        Argument(u"user", u"string", u"user name", metavar=u"username"),
        Argument(u"pass", u"string", u"password", metavar=u"password")
    ]
    docCallSyntax = CallSyntax(docArgs, u"?{0}&{1}")
    docReturnValue = u"Returns the session id on success or “failed: message” in case of an error, whereas message will be replaced by the error message."

    def __init__(self, model):
        super(SessionAPI, self).__init__(model)
        self.allowedMethods = frozenset(["GET", "POST"])

    def handle(self, trans):
        trans.hide_post = True
        trans.set_content_type(ContentType("text/plain", self.encoding))
        if (not "user" in self.query) or (not "pass" in self.query):
            if "cookie" in self.query:
                trans.set_content_type(ContentType("text/html", self.encoding))
                print >> self.out, u"""<html>
    <head>
        <title>{0}</title>
    </head>
    <body>
        <form name="login" action="getSession?cookie" method="POST">
            Username: <input type="text" name="user" value="" /><br />
            Password: <input type="password" name="pass" value="" /><br />
            <input type="submit" name="submit" value="Login" />
        </form>
    </body>
</html>""".format(self.model.formatHTMLTitle(u"Login")).encode(
                    self.encoding, 'replace')
                return
            else:
                print >> self.out, (
                    u"failed: need user and pass arguments").encode(
                        self.encoding)
                return
        userName = self.query["user"]
        password = self.query["pass"]

        user = self.store.find(APIUser, APIUser.UserName == userName).any()
        if user is None:
            print >> self.out, (u"failed: user (%s) not found" %
                                userName).encode(self.encoding)
            return
        if not user.checkPassword(password):
            print >> self.out, (u"failed: password invalid").encode(
                self.encoding)
            return
        password = None
        session = user.getSession()
        if "cookie" in self.query:
            trans.set_cookie_value("priyom-api-session",
                                   trans.encode_cookie_value(session.Key), '/',
                                   session.Expires)
            trans.set_content_type(ContentType("text/plain", self.encoding))
            print >> self.out, u"You are now logged in (a cookie has been set).".encode(
                self.encoding, 'replace')
        else:
            print >> self.out, session.Key.encode(self.encoding, 'replace')