Beispiel #1
0
 def async_run(self):
     while True:
         try:
             event = self.internal_queue.get(block=True, timeout=1)
             event()
         except Empty:
             pass
         except Exception:
             L.error("Exception:\n" + traceback.format_exc())
Beispiel #2
0
    def modify(self, operations, partial):
        status = self.query()
        last_text = ""
        today = datetime.datetime.now(tz=self.met)
        for i in sorted(operations):
            if i.month == 1 and today.month == 12:
                mes = 1
            else:
                mes = i.month - today.month
            if mes not in (0, 1):
                L.error(str(i) + " is neither current nor next month")
                partial(str(i) + " no es parte del mes actual o siguiente")
                continue

            if operations[i] == DayStatus.TO_REQUEST:
                if i not in status or status[i].status in (
                    DayStatus.RESERVED,
                    DayStatus.NOT_AVAILABLE,
                    DayStatus.REQUESTED,
                    DayStatus.BUSY,
                ):
                    partial(str(i) + " está ya solicitado")
                    continue
            if operations[i] in (DayStatus.TO_FREE, DayStatus.TO_UNREQUEST):
                # Operation is to free/unrequest
                if i not in status or status[i].status in (DayStatus.AVAILABLE, DayStatus.NOT_AVAILABLE):
                    partial(str(i) + " está ya liberado")
                    continue
            try:
                L.debug("Requesting " + str(i) + ": " + self.map_operation(operations[i]))
                r = self.session.post(
                    "http://" + self.host + "/perfil.php", data={"dia": i.day, "mes": mes, "libre": operations[i]}
                )

                if r.status_code != requests.codes.ok:
                    L.error("Failed request on " + self.host + ", response:" + r)
                    partial(str(i) + "`: Failed request on server response:" + r)
                    continue

                # Parse the web page to obtain the result message
                last_text = self.get_response_text(r)
                result = self.parse_result(last_text)
                if result == "":
                    result = "La modificación de " + str(i) + " no fue aceptada"
                partial(result)
                L.info(str(i) + ": " + result)
            except (KeyboardInterrupt, requests.ConnectionError):
                L.debug("Petición fallida en " + self.host + ", con:\n" + traceback.format_exc())

        if last_text != "":
            return self.parse_months(last_text)
        else:
            # We didn't send any operation, use the status retrieved
            # when we entered the method.
            return status
Beispiel #3
0
    def add_fake_request(self,msg):
        if msg['response'] == 'ping':
            request=Ping()
        elif msg['response'] == 'query':
            request=Refresh()
        elif msg['response'] == 'modify':
            request=Modify()
        else:
            L.error("Respuesta desconocida %s" % msg['response'])

        request.id=msg['id']
        self.pending[request.id] = request
Beispiel #4
0
 def run(self):
     while True:
         try:
             osc.readQueue(self.oscid)
             if not self.notified:
                 self.update_notification("Intento: " + self.last_time.strftime('%Y-%m-%d %H:%M'))
                 self.notified = True
             if self.check_pattern():
                 self.add_pattern()
             # Pending operations
             if self.check_interval():
                 # Update last_time here to avoid repeated requests
                 self.last_time = datetime.datetime.now(tz=self.met)
                 self.internal_queue.put(lambda: self.modify(-1))
         except:
             L.error("Exception:\n" + traceback.format_exc())
         sleep(.1)
Beispiel #5
0
 def update_notification(self, text):
     L.info("Notification: " + text)
     if platform == 'android':
         try:
             service = PythonService.mService
             builder = NotificationBuilder(service)
             builder.setSmallIcon(service.getApplicationInfo().icon)
             builder.setContentTitle("AndroidPark(ing)")
             builder.setContentText(text)
             context_intent = Intent(service, Class.forName('org.renpy.android.PythonActivity'))
             pending_intent = PendingIntent.getActivity(service, 0, context_intent,
                                                        PendingIntent.FLAG_UPDATE_CURRENT)
             builder.setContentIntent(pending_intent)
             manager = service.getSystemService(Context.NOTIFICATION_SERVICE)
             manager.notify(1, builder.build())
         except:
             L.error("Exception:\n" + traceback.format_exc())
Beispiel #6
0
    def update_info(self, state, pending, status=None):
        self.status_bar.text = ""
        if not state:
            L.error("state is None")
            self.querying.dismiss()
            if status is not None:
                self.error.text = status
            else:
                self.error.text = "Error desconocido"
            self.error.open()
            return

        self.unrequest_month(self.current_month)
        self.unrequest_month(self.next_month)
        self.current_month.update(state, pending)
        self.next_month.update(state, pending)
        L.debug("Update ends")
        self.querying.dismiss()
Beispiel #7
0
    def update_pending(self, result):
        """
        Update the pending operations with the result retrieved from the web.
        :param result:
        :return: None
        """
        self.check_next_month(result)
        to_delete = []

        L.info("pending (before) " + str(self.pending))

        for i in sorted(self.pending):
            today = datetime.datetime.now(tz=self.met)
            if(i.month==1 and today.month==12):
                mes = 1
            else:
                mes = i.month - today.month
            if mes not in (0, 1):
                L.error(str(i) + " is neither current nor next month")
                to_delete.append(i)
                continue
            if self.pending[i] == DayStatus.TO_FREE:
                # Request was to Free... target should be Free.
                if i not in result or result[i].status in (DayStatus.AVAILABLE, DayStatus.NOT_AVAILABLE):
                    to_delete.append(i)

            if self.pending[i] == DayStatus.TO_REQUEST:
                # Request was to Request.... target is Assigned.
                if i not in result or result[i].status in (DayStatus.RESERVED, DayStatus.NOT_AVAILABLE):
                    to_delete.append(i)

            if self.pending[i] == DayStatus.TO_UNREQUEST:
                # Request was to Unrequest.
                if i not in result or result[i].status in (DayStatus.AVAILABLE, DayStatus.NOT_AVAILABLE):
                    to_delete.append(i)

        for i in to_delete:
            del self.pending[i]

        for i in [i for i in result if result[i].status == DayStatus.REQUESTED]:
            self.pending[i] = DayStatus.TO_REQUEST

        L.info("pending (after) " + str(self.pending))
Beispiel #8
0
    def query(self):
        L.debug("Starting query")

        if self.session is None:
            #
            # No session, start a login session
            # the result is fine as a query result
            #
            state = self.login()
            return state

        #
        # Reuse session
        #
        try:
            r = self.session.get("http://" + self.host + "/perfil.php")
            if r.status_code != requests.codes.ok:
                status = "Error consultando al " + self.host + ", respuesta:" + r
                raise ServerException(status)
            #
            # Parse the web page we have read
            #
            L.debug("Parsing query result")
            state = self.parse_months(self.get_response_text(r))

            if state is None:
                L.debug("parsing failed, login might have failed")
                self.session = None
                return self.query()

        except (KeyboardInterrupt, requests.ConnectionError, ServerException):
            L.error(traceback.format_exc())
            # try to login again
            self.session = None
            return self.query()

        return state
Beispiel #9
0
    def parse_months(self, text):
        """
        Parse the web page to obtain the
        list of the days and their status
        :param text: the text from the http response
        :return: a dictionary with the status of the days
        """
        result = []
        out = {}

        soup = bs4.BeautifulSoup(text, "html5lib")
        # get the cells... this is better reference I could get
        toptables = soup.select("body > table ")

        if len(toptables) != 6:
            L.error("Parsing: did not found 6 tables")
            return None

        tables = [toptables[4].tbody.tr.td.table, toptables[5].tbody.contents[1].td.table]

        # Now, for each table.
        for t in tables:
            month = []
            # for each week (row)
            for w in t.select("tr"):
                # for each day (cell)
                for d in w.select("td"):
                    # only pay attention to colored cells
                    if "bgcolor" in d.attrs:
                        # Try to parse the cell
                        cell_list = d.select("div")
                        if len(cell_list) == 0:
                            # No divs... not interested in this
                            continue
                        elif len(cell_list) < 2:
                            # only one div
                            day = cell_list[0]
                            slot = None
                        else:
                            # two divs.
                            (day, slot) = cell_list

                        # some days appear with two nested divs.
                        if day.string is not None:
                            mday = int(day.string.strip())
                        else:
                            mday = int([x for x in day.stripped_strings][0])
                        rslot = None
                        # parse the status based on the color
                        if d.attrs["bgcolor"] == "#999999":
                            status = DayStatus.NOT_AVAILABLE
                        elif d.attrs["bgcolor"] == "#FF9900":
                            status = DayStatus.RESERVED
                            if slot is not None:
                                rslot = [x for x in slot.stripped_strings][0]
                        elif d.attrs["bgcolor"] == "#339900":
                            status = DayStatus.AVAILABLE
                        elif d.attrs["bgcolor"] == "#000000":
                            status = DayStatus.REQUESTED
                        else:
                            status = DayStatus.BUSY
                        month.append(DayStatus(mday, status, rslot))
            result.append(month)

        if len(result) != 2:
            L.error("Parsing: did not found 2 months")
            return None
        # Now rebuild the date
        today = datetime.datetime.now(tz=self.met)
        today = datetime.date(today.year, today.month, 1)
        for d in [x.fix(today) for x in result[0]]:
            out[d.date] = d
        for d in [x.fix(today + datetime.timedelta(days=31)) for x in result[1]]:
            out[d.date] = d

        busy = len([x for x in out if out[x].status == DayStatus.BUSY])
        requested = len([x for x in out if out[x].status == DayStatus.REQUESTED])
        reserved = len([x for x in out if out[x].status == DayStatus.RESERVED])
        available = len([x for x in out if out[x].status == DayStatus.AVAILABLE])
        L.info("Parsed: %d busy,%d requested, %d reserved, %d available" % (busy, requested, reserved, available))
        return out
Beispiel #10
0
 def check_timeout(self):
     now = datetime.datetime.now()
     timedout_id = [_id for _id in self.pending if self.pending[_id].endtime < now]
     timedout = [self.get_id(_id) for _id in timedout_id]
     map(lambda (x): L.error("Time out on %d" % x.id), timedout)
     map(lambda (x): x.timedout(), timedout)