Beispiel #1
0
    def get_list(self):
        accounts = OrderedDict()

        for tr in self.document.getiterator("tr"):
            first_td = tr.getchildren()[0]
            if (
                first_td.attrib.get("class", "") == "i g" or first_td.attrib.get("class", "") == "p g"
            ) and first_td.find("a") is not None:

                a = first_td.find("a")
                link = a.get("href", "")
                if link.startswith("POR_SyntheseLst"):
                    continue

                url = urlparse(link)
                p = parse_qs(url.query)
                if not "rib" in p:
                    continue

                for i in (2, 1):
                    balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text)
                    currency = Account.get_currency(tr.getchildren()[i].text)
                    if len(balance) > 0:
                        break
                balance = Decimal(balance)

                id = p["rib"][0]
                if id in accounts:
                    account = accounts[id]
                    if not account.coming:
                        account.coming = Decimal("0.0")
                    account.coming += balance
                    account._card_links.append(link)
                    continue

                account = Account()
                account.id = id
                account.label = unicode(a.text).strip().lstrip(" 0123456789").title()
                account._link_id = link
                account._card_links = []

                # Find accounting amount
                page = self.browser.get_document(self.browser.openurl(link))
                coming = self.find_amount(page, u"Opérations à venir")
                accounting = self.find_amount(page, u"Solde comptable")

                if accounting is not None and accounting + (coming or Decimal("0")) != balance:
                    self.logger.warning("%s + %s != %s" % (accounting, coming, balance))

                if accounting is not None:
                    balance = accounting

                if coming is not None:
                    account.coming = coming
                account.balance = balance
                account.currency = currency

                accounts[account.id] = account

        return accounts.itervalues()
Beispiel #2
0
    def format(self, obj, selected_fields=None):
        """
        Format an object to be human-readable.
        An object has fields which can be selected.
        If the object provides an iter_fields() method, the formatter will
        call it. It can be used to specify the fields order.

        @param obj  [object] object to format
        @param selected_fields  [tuple] fields to display. If None, all fields are selected
        @return  a string of the formatted object
        """
        assert isinstance(obj, (dict, CapBaseObject, tuple))

        if isinstance(obj, dict):
            item = obj
        elif isinstance(obj, tuple):
            item = OrderedDict([(k, v) for k, v in obj])
        else:
            item = self.to_dict(obj, selected_fields)

        if item is None:
            return None

        if self.MANDATORY_FIELDS:
            missing_fields = set(self.MANDATORY_FIELDS) - set(item.keys())
            if missing_fields:
                raise MandatoryFieldsNotFound(missing_fields)

        formatted = self.format_dict(item=item)
        if formatted:
            self.after_format(formatted)
        return formatted
Beispiel #3
0
    def get_list(self):
        accounts = OrderedDict()

        # Old website
        for table in self.document.xpath('//table[@cellpadding="1"]'):
            account_type = Account.TYPE_UNKNOWN
            for tr in table.xpath("./tr"):
                tds = tr.findall("td")
                if tr.attrib.get("class", "") == "DataGridHeader":
                    account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip(), Account.TYPE_UNKNOWN)
                else:
                    label = ""
                    i = 1
                    a = None
                    while label == "" and i < len(tds):
                        a = tds[i].find("a")
                        if a is None:
                            continue

                        label = self.parser.tocleanstring(a)
                        i += 1

                    balance = ""
                    i = -1
                    while balance == "" and i > -len(tds):
                        try:
                            balance = self.parser.tocleanstring(tds[i].xpath("./a")[0])
                        except KeyError:
                            balance = u"".join([txt.strip() for txt in tds[i].itertext()])
                        i -= 1
                    self._add_account(accounts, a, label, account_type, balance)

        if len(accounts) == 0:
            # New website
            for table in self.document.xpath('//div[@class="panel"]'):
                title = table.getprevious()
                if title is None:
                    continue
                account_type = self.ACCOUNT_TYPES.get(self.parser.tocleanstring(title), Account.TYPE_UNKNOWN)
                for tr in table.xpath(".//tr"):
                    tds = tr.findall("td")
                    for i in xrange(len(tds)):
                        a = tds[i].find("a")
                        if a is not None:
                            break

                    if a is None:
                        continue

                    label = self.parser.tocleanstring(tds[0])
                    balance = self.parser.tocleanstring(tds[-1])

                    self._add_account(accounts, a, label, account_type, balance)

        return accounts.itervalues()
Beispiel #4
0
    def get_profile(self):
        title = self.parser.select(self.document.getroot(), "title", 1)
        if title.text == "OkCupid: Account Not Found":
            return None

        profile = {}
        profile["id"] = unicode(title.text[len("OkCupid: ") :])
        profile["data"] = OrderedDict()

        profile_p = self.parser.select(
            self.document.getroot(), "//div[@id='page_content']//div[contains(@class, 'basics')]//p", method="xpath"
        )

        profile["data"]["infos"] = ProfileNode("infos", u"Informations", OrderedDict(), flags=ProfileNode.SECTION)

        info = {
            "age": profile_p[1].text.split(u"•", 1)[0].strip(),
            "location": profile_p[1].text.split(u"•", 1)[1].strip(),
            "sex": profile_p[2].text.strip(),
        }

        for key, val in info.iteritems():
            profile["data"]["infos"].value[key] = ProfileNode(key, key.capitalize(), val)

        div_essays = self.parser.select(self.document.getroot(), "//div[@class='essay']", method="xpath")
        h3_essays = self.parser.select(self.document.getroot(), "//div[@id='page_content']//h3", method="xpath")
        essays = OrderedDict(zip(h3_essays, div_essays))

        profile["data"]["look_for"] = ProfileNode("look_for", u"Look for", OrderedDict(), flags=ProfileNode.SECTION)
        profile["data"]["details"] = ProfileNode("details", u"Details", OrderedDict(), flags=ProfileNode.SECTION)
        profile["data"]["essays"] = ProfileNode("essays", u"Essays", OrderedDict(), flags=ProfileNode.SECTION)

        for label, val in essays.iteritems():
            label = unicode(label.text).strip()
            txt = self.parser.tocleanstring(val)
            if "looking for" in label:
                for i, li in enumerate(val.xpath(".//li")):
                    profile["data"]["look_for"].value["look_for_%s" % i] = ProfileNode(
                        "look_for_%s" % i, "", li.text.strip()
                    )
            elif "summary" in label and "summary" not in profile:
                profile["summary"] = txt
            else:
                key = label.replace(" ", "_")
                profile["data"]["essays"].value[key] = ProfileNode(key, label, txt)

        details_div = self.parser.select(self.document.getroot(), "//div[@id='details']//li", method="xpath")
        for elem in details_div:
            label = unicode(elem.getchildren()[0].text.strip())
            val = unicode(elem.getchildren()[1].text.strip())
            key = label.lower().replace(" ", "_")
            profile["data"]["details"].value[key] = ProfileNode(key, label, val)

        return profile
Beispiel #5
0
    def on_loaded(self):
        for script in self.document.xpath("//script"):
            text = script.text
            if text is None:
                continue
            m = re.search("window.location.replace\('([^']+)'\);", text)
            if m:
                self.browser.location(m.group(1))

        try:
            self.browser.select_form(name="banque")
        except FormNotFoundError:
            pass
        else:
            self.browser.set_all_readonly(False)
            accounts = OrderedDict()
            for tr in self.document.getroot().cssselect("table.compteTable > tbody > tr"):
                if len(tr.findall("td")) == 0:
                    continue
                attr = tr.xpath(".//a")[0].attrib.get("onclick", "")
                m = re.search("value = '(\w+)';(checkAndSubmit\('\w+','(\w+)','(\w+)'\))?", attr)
                if m:
                    typeCompte = m.group(1)
                    tagName = m.group(3)
                    if tagName is not None:
                        value = self.document.xpath('//input[@name="%s"]' % m.group(3))[int(m.group(4))].attrib["value"]
                    else:
                        value = typeCompte
                    accounts[value] = (typeCompte, tagName)

            try:
                typeCompte, tagName = accounts[self.browser.accnum]
                value = self.browser.accnum
            except KeyError:
                accnums = ", ".join(accounts.keys())
                if self.browser.accnum != "00000000000":
                    self.logger.warning(
                        u'Unable to find account "%s". Available ones: %s' % (self.browser.accnum, accnums)
                    )
                elif len(accounts) > 1:
                    self.logger.warning(
                        'There are several accounts, please use "accnum" backend parameter to force the one to use (%s)'
                        % accnums
                    )
                value, (typeCompte, tagName) = accounts.popitem(last=False)
            self.browser["typeCompte"] = typeCompte
            if tagName is not None:
                self.browser[tagName] = [value]
            self.browser.submit()
Beispiel #6
0
 def on_loaded(self):
     self.accounts = OrderedDict()
     self.parse_table("comptes")
     self.parse_table("comptesEpargne")
     self.parse_table("comptesTitres")
     self.parse_table("comptesVie")
     self.parse_table("comptesRetraireEuros")
Beispiel #7
0
 def on_loaded(self):
     self.accounts = OrderedDict()
     self.parse_table("comptes", Account.TYPE_CHECKING)
     self.parse_table("comptesEpargne", Account.TYPE_SAVINGS)
     self.parse_table("comptesTitres", Account.TYPE_MARKET)
     self.parse_table("comptesVie", Account.TYPE_DEPOSIT)
     self.parse_table("comptesRetraireEuros")
Beispiel #8
0
    def get_list(self):
        accounts = OrderedDict()

        for tr in self.document.getiterator("tr"):
            first_td = tr.getchildren()[0]
            if (
                first_td.attrib.get("class", "") == "i g" or first_td.attrib.get("class", "") == "p g"
            ) and first_td.find("a") is not None:

                a = first_td.find("a")
                link = a.get("href", "")
                if link.startswith("POR_SyntheseLst"):
                    continue

                url = urlparse(link)
                p = parse_qs(url.query)
                if not "rib" in p:
                    continue

                for i in (2, 1):
                    balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text.strip(" EUR"))
                    if len(balance) > 0:
                        break
                balance = Decimal(balance)

                id = p["rib"][0]
                if id in accounts:
                    account = accounts[id]
                    if not account.coming:
                        account.coming = Decimal("0.0")
                    account.coming += balance
                    account._card_links.append(link)
                    continue

                account = Account()
                account.id = id
                account.label = unicode(a.text).strip().lstrip(" 0123456789").title()
                account._link_id = link
                account._card_links = []

                account.balance = balance

                accounts[account.id] = account

        return accounts.itervalues()
Beispiel #9
0
 def on_loaded(self):
     if self.document.xpath(u'//h2[text()="%s"]' % u"ERREUR"):
         raise BrowserUnavailable()
     self.accounts = OrderedDict()
     self.parse_table("comptes", Account.TYPE_CHECKING)
     self.parse_table("comptesEpargne", Account.TYPE_SAVINGS)
     self.parse_table("comptesTitres", Account.TYPE_MARKET)
     self.parse_table("comptesVie", Account.TYPE_DEPOSIT)
     self.parse_table("comptesRetraireEuros")
Beispiel #10
0
class AccountList(Page):
    def on_loaded(self):
        if self.document.xpath(u'//h2[text()="%s"]' % u"ERREUR"):
            raise BrowserUnavailable()
        self.accounts = OrderedDict()
        self.parse_table("comptes", Account.TYPE_CHECKING)
        self.parse_table("comptesEpargne", Account.TYPE_SAVINGS)
        self.parse_table("comptesTitres", Account.TYPE_MARKET)
        self.parse_table("comptesVie", Account.TYPE_DEPOSIT)
        self.parse_table("comptesRetraireEuros")

    def get_accounts_list(self):
        return self.accounts.itervalues()

    def parse_table(self, what, actype=Account.TYPE_UNKNOWN):
        tables = self.document.xpath("//table[@id='%s']" % what, smart_strings=False)
        if len(tables) < 1:
            return

        lines = tables[0].xpath(".//tbody/tr")
        for line in lines:
            account = Account()
            tmp = line.xpath("./td//a")[0]
            account.label = to_unicode(tmp.text)
            account.type = actype
            account._link_id = tmp.get("href")
            if "BourseEnLigne" in account._link_id:
                account.type = Account.TYPE_MARKET

            tmp = line.xpath("./td/span/strong")
            if len(tmp) >= 2:
                tmp_id = tmp[0].text
                tmp_balance = tmp[1].text
            else:
                tmp_id = line.xpath("./td//span")[1].text
                tmp_balance = tmp[0].text

            account.id = tmp_id
            account.currency = account.get_currency(tmp_balance)
            account.balance = Decimal(FrenchTransaction.clean_amount(tmp_balance))

            if account.id in self.accounts:
                a = self.accounts[account.id]
                a._card_links.append(account._link_id)
                if not a.coming:
                    a.coming = Decimal("0.0")
                a.coming += account.balance
            else:
                account._card_links = []
                self.accounts[account.id] = account

    def get_account(self, id):
        try:
            return self.accounts[id]
        except KeyError:
            raise AccountNotFound("Unable to find account: %s" % id)
Beispiel #11
0
    def get_list(self):
        accounts = OrderedDict()

        # Old website
        for table in self.document.xpath('//table[@cellpadding="1"]'):
            account_type = Account.TYPE_UNKNOWN
            for tr in table.xpath("./tr"):
                tds = tr.findall("td")
                if tr.attrib.get("class", "") == "DataGridHeader":
                    account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip(), Account.TYPE_UNKNOWN)
                else:
                    # On the same row, there are many accounts (for example a
                    # check accound and a card one).
                    for i, a in enumerate(tds[2].xpath("./a")):
                        label = self.parser.tocleanstring(a)
                        balance = self.parser.tocleanstring(tds[-2].xpath("./a")[i])
                        self._add_account(accounts, a, label, account_type, balance)

        if len(accounts) == 0:
            # New website
            for table in self.document.xpath('//div[@class="panel"]'):
                title = table.getprevious()
                if title is None:
                    continue
                account_type = self.ACCOUNT_TYPES.get(self.parser.tocleanstring(title), Account.TYPE_UNKNOWN)
                for tr in table.xpath(".//tr"):
                    tds = tr.findall("td")
                    for i in xrange(len(tds)):
                        a = tds[i].find("a")
                        if a is not None:
                            break

                    if a is None:
                        continue

                    label = self.parser.tocleanstring(tds[0])
                    balance = self.parser.tocleanstring(tds[-1])

                    self._add_account(accounts, a, label, account_type, balance)

        return accounts.itervalues()
Beispiel #12
0
 def __init__(self, name, backend):
     self.my_id = backend.browser.get_userid()
     self.name = "wiki/weboob/%s" % name
     self.description = None
     self.date = None
     self.begin = None
     self.end = None
     self.location = None
     self.winner = None
     self.backend = backend
     self.members = OrderedDict()
     self.load()
Beispiel #13
0
    def parse_profile(self, profile, consts):
        if profile["online"]:
            self.status = Contact.STATUS_ONLINE
            self.status_msg = u"online"
            self.status_msg = u"since %s" % profile["last_cnx"]
        else:
            self.status = Contact.STATUS_OFFLINE
            self.status_msg = u"last connection %s" % profile["last_cnx"]

        self.summary = unicode(unescape(profile.get("announce", "").strip()))
        if len(profile.get("shopping_list", "")) > 0:
            self.summary += u"\n\nLooking for:\n%s" % unescape(profile["shopping_list"].strip())

        for photo in profile["pics"]:
            self.set_photo(photo.split("/")[-1], url=photo + "/full", thumbnail_url=photo + "/small", hidden=False)
        self.profile = OrderedDict()

        if "sex" in profile:
            for section, d in self.TABLE.iteritems():
                flags = ProfileNode.SECTION
                if section.startswith("_"):
                    flags |= ProfileNode.HEAD
                if (section.startswith("+") and int(profile["sex"]) != 1) or (
                    section.startswith("-") and int(profile["sex"]) != 0
                ):
                    continue

                section = section.lstrip("_+-")

                s = ProfileNode(section, section.capitalize(), OrderedDict(), flags=flags)

                for key, builder in d.iteritems():
                    try:
                        value = builder.get_value(profile, consts[int(profile["sex"])])
                    except KeyError:
                        pass
                    else:
                        s.value[key] = ProfileNode(key, key.capitalize().replace("_", " "), value)

                self.profile[section] = s

        self._aum_profile = profile
Beispiel #14
0
    def format(self, obj, selected_fields=None, alias=None):
        """
        Format an object to be human-readable.
        An object has fields which can be selected.

        :param obj: object to format
        :type obj: CapBaseObject or dict
        :param selected_fields: fields to display. If None, all fields are selected
        :type selected_fields: tuple
        :param alias: an alias to use instead of the object's ID
        :type alias: unicode
        """
        if isinstance(obj, CapBaseObject):
            if selected_fields is not None and not "*" in selected_fields:
                obj = obj.copy()
                for name, value in obj.iter_fields():
                    if not name in selected_fields:
                        delattr(obj, name)

            if self.MANDATORY_FIELDS:
                missing_fields = set(self.MANDATORY_FIELDS) - set([name for name, value in obj.iter_fields()])
                if missing_fields:
                    raise MandatoryFieldsNotFound(missing_fields)

            formatted = self.format_obj(obj, alias)
        else:
            try:
                obj = OrderedDict(obj)
            except ValueError:
                raise TypeError("Please give a CapBaseObject or a dict")

            if selected_fields is not None and not "*" in selected_fields:
                obj = obj.copy()
                for name, value in obj.iteritems():
                    if not name in selected_fields:
                        obj.pop(name)

            if self.MANDATORY_FIELDS:
                missing_fields = set(self.MANDATORY_FIELDS) - set(obj.iterkeys())
                if missing_fields:
                    raise MandatoryFieldsNotFound(missing_fields)

            formatted = self.format_dict(obj)

        if formatted:
            self.output(formatted)
        return formatted
Beispiel #15
0
    def registerEvent(self):
        selection = self.ui.backendsList.selectedItems()
        if not selection:
            return

        try:
            backend = self.weboob.modules_loader.get_or_load_module(unicode(selection[0].text()).lower())
        except ModuleLoadError:
            backend = None

        if not backend:
            return

        dialog = QDialog(self)
        vbox = QVBoxLayout(dialog)
        if backend.website:
            website = "on the website <b>%s</b>" % backend.website
        else:
            website = "with the backend <b>%s</b>" % backend.name
        vbox.addWidget(QLabel("To create an account %s, please give these informations:" % website))
        formlayout = QFormLayout()
        props_widgets = OrderedDict()
        for key, prop in backend.klass.ACCOUNT_REGISTER_PROPERTIES.iteritems():
            widget = QtValue(prop)
            formlayout.addRow(QLabel(u"%s:" % prop.label), widget)
            props_widgets[prop.id] = widget

        vbox.addLayout(formlayout)
        buttonBox = QDialogButtonBox(dialog)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.connect(buttonBox, SIGNAL("accepted()"), dialog.accept)
        self.connect(buttonBox, SIGNAL("rejected()"), dialog.reject)
        vbox.addWidget(buttonBox)

        end = False
        while not end:
            end = True
            if dialog.exec_():
                account = Account()
                account.properties = {}
                for key, widget in props_widgets.iteritems():
                    try:
                        v = widget.get_value()
                    except ValueError, e:
                        QMessageBox.critical(
                            self,
                            self.tr("Invalid value"),
                            unicode(self.tr('Invalid value for field "%s":<br /><br />%s')) % (key, e),
                        )
                        end = False
                        break
                    else:
                        account.properties[key] = v
                if end:
                    try:
                        backend.klass.register_account(account)
                    except AccountRegisterError, e:
                        QMessageBox.critical(
                            self,
                            self.tr("Error during register"),
                            unicode(self.tr("Unable to register account %s:<br /><br />%s")) % (website, e),
                        )
                        end = False
                    else:
                        for key, value in account.properties.iteritems():
                            if key in self.config_widgets:
                                self.config_widgets[key][1].set_data(value.value)
Beispiel #16
0
class Contact(_Contact):
    TABLE = OrderedDict(
        (
            (
                "_info",
                OrderedDict(
                    (
                        ("title", FieldStr("title")),
                        # ipaddr is not available anymore.
                        # ('IPaddr',              FieldIP('last_ip', 'first_ip')),
                        ("admin", FieldBool("admin")),
                        ("ban", FieldBool("isBan")),
                        ("first", FieldStr("first_cnx")),
                        ("godfather", FieldProfileURL("godfather")),
                    )
                ),
            ),
            (
                "_stats",
                OrderedDict(
                    (
                        ("mails", FieldPopu("mails")),
                        ("charms", FieldPopu("charmes")),
                        ("visites", FieldPopu("visites")),
                        ("baskets", FieldPopu("panier")),
                        ("invits", FieldPopu("invits")),
                        ("bonus", FieldPopu("bonus")),
                        ("score", FieldStr("points")),
                        ("ratio", FieldPopuRatio("mails", "charmes")),
                        ("mailable", FieldBool("can_mail")),
                    )
                ),
            ),
            (
                "details",
                OrderedDict(
                    (
                        # ('old',                 FieldStr('age')),
                        ("old", FieldOld("birthdate")),
                        ("birthday", FieldStr("birthdate")),
                        ("zipcode", FieldStr("zip")),
                        ("location", FieldStr("city")),
                        ("distance", FieldDist("dist")),
                        ("country", FieldStr("country")),
                        ("phone", FieldStr("phone")),
                        ("eyes", FieldConst("eyes_color")),
                        ("hair_color", FieldConst("hair_color")),
                        ("hair_size", FieldConst("hair_size")),
                        ("height", FieldConst("size")),
                        ("weight", FieldConst("weight")),
                        ("BMI", FieldBMI("size", "weight")),
                        ("fat", FieldBMI("size", "weight", fat=True)),
                        ("shape", FieldConst("shape")),
                        ("origins", FieldConst("origins")),
                        ("signs", FieldConst("features")),
                        ("job", FieldStr("job")),
                        ("style", FieldConst("styles")),
                        ("food", FieldConst("diet")),
                        ("favorite_food", FieldConst("favourite_food")),
                        ("drink", FieldConst("alcohol")),
                        ("smoke", FieldConst("tobacco")),
                    )
                ),
            ),
            (
                "tastes",
                OrderedDict(
                    (
                        ("hobbies", FieldStr("hobbies")),
                        ("music", FieldList("music")),
                        ("cinema", FieldList("cinema")),
                        ("books", FieldList("books")),
                        ("tv", FieldList("tvs")),
                    )
                ),
            ),
            (
                "+sex",
                OrderedDict(
                    (
                        ("underwear", FieldConst("underwear")),
                        ("practices", FieldConst("sexgames")),
                        ("favorite", FieldConst("arousing")),
                        ("toys", FieldConst("sextoys")),
                    )
                ),
            ),
            (
                "+personality",
                OrderedDict(
                    (
                        ("snap", FieldStr("fall_for")),
                        ("exciting", FieldStr("turned_on_by")),
                        ("hate", FieldStr("cant_stand")),
                        ("vices", FieldStr("vices")),
                        ("assets", FieldStr("assets")),
                        ("fantasies", FieldStr("fantasies")),
                        ("is", FieldConst("character")),
                    )
                ),
            ),
            (
                "-personality",
                OrderedDict(
                    (
                        ("accessories", FieldConst("accessories")),
                        ("skills", FieldConst("skills")),
                        ("socios", FieldConst("socios")),
                        ("family", FieldConst("family")),
                        ("pets", FieldConst("pets")),
                    )
                ),
            ),
        )
    )

    def parse_profile(self, profile, consts):
        if profile["online"]:
            self.status = Contact.STATUS_ONLINE
            self.status_msg = u"online"
            self.status_msg = u"since %s" % profile["last_cnx"]
        else:
            self.status = Contact.STATUS_OFFLINE
            self.status_msg = u"last connection %s" % profile["last_cnx"]

        self.summary = unicode(unescape(profile.get("announce", "").strip()))
        if len(profile.get("shopping_list", "")) > 0:
            self.summary += u"\n\nLooking for:\n%s" % unescape(profile["shopping_list"].strip())

        for photo in profile["pics"]:
            self.set_photo(photo.split("/")[-1], url=photo + "/full", thumbnail_url=photo + "/small", hidden=False)
        self.profile = OrderedDict()

        if "sex" in profile:
            for section, d in self.TABLE.iteritems():
                flags = ProfileNode.SECTION
                if section.startswith("_"):
                    flags |= ProfileNode.HEAD
                if (section.startswith("+") and int(profile["sex"]) != 1) or (
                    section.startswith("-") and int(profile["sex"]) != 0
                ):
                    continue

                section = section.lstrip("_+-")

                s = ProfileNode(section, section.capitalize(), OrderedDict(), flags=flags)

                for key, builder in d.iteritems():
                    try:
                        value = builder.get_value(profile, consts[int(profile["sex"])])
                    except KeyError:
                        pass
                    else:
                        s.value[key] = ProfileNode(key, key.capitalize().replace("_", " "), value)

                self.profile[section] = s

        self._aum_profile = profile

    def get_text(self):
        def print_node(node, level=1):
            result = u""
            if node.flags & node.SECTION:
                result += u"\t" * level + node.label + "\n"
                for sub in node.value.itervalues():
                    result += print_node(sub, level + 1)
            else:
                if isinstance(node.value, (tuple, list)):
                    value = ", ".join(unicode(v) for v in node.value)
                elif isinstance(node.value, float):
                    value = "%.2f" % node.value
                else:
                    value = node.value
                result += u"\t" * level + u"%-20s %s\n" % (node.label + ":", value)
            return result

        result = u"Nickname: %s\n" % self.name
        if self.status & Contact.STATUS_ONLINE:
            s = "online"
        elif self.status & Contact.STATUS_OFFLINE:
            s = "offline"
        elif self.status & Contact.STATUS_AWAY:
            s = "away"
        else:
            s = "unknown"
        result += u"Status: %s (%s)\n" % (s, self.status_msg)
        result += u"URL: %s\n" % self.url
        result += u"Photos:\n"
        for name, photo in self.photos.iteritems():
            result += u"\t%s%s\n" % (photo, " (hidden)" if photo.hidden else "")
        result += u"\nProfile:\n"
        for head in self.profile.itervalues():
            result += print_node(head)
        result += u"Description:\n"
        for s in self.summary.split("\n"):
            result += u"\t%s\n" % s
        return result
Beispiel #17
0
class ListElement(AbstractElement):
    item_xpath = None
    flush_at_end = False
    ignore_duplicate = False

    def __init__(self, *args, **kwargs):
        super(ListElement, self).__init__(*args, **kwargs)
        self.logger = getLogger(self.__class__.__name__.lower())
        self.objects = OrderedDict()

    def __call__(self, *args, **kwargs):
        for key, value in kwargs.iteritems():
            self.env[key] = value

        return self.__iter__()

    def find_elements(self):
        """
        Get the nodes that will have to be processed.
        This method can be overridden if xpath filters are not
        sufficient.
        """
        if self.item_xpath is not None:
            for el in self.el.xpath(self.item_xpath):
                yield el
        else:
            yield self.el

    def __iter__(self):
        self.parse(self.el)

        items = []
        for el in self.find_elements():
            for attrname in dir(self):
                attr = getattr(self, attrname)
                if isinstance(attr, type) and issubclass(attr, AbstractElement) and attr != type(self):
                    item = attr(self.page, self, el)
                    item.handle_loaders()
                    items.append(item)

        for item in items:
            for obj in item:
                obj = self.store(obj)
                if obj and not self.flush_at_end:
                    yield obj

        if self.flush_at_end:
            for obj in self.flush():
                yield obj

        self.check_next_page()

    def flush(self):
        for obj in self.objects.itervalues():
            yield obj

    def check_next_page(self):
        if not hasattr(self, "next_page"):
            return

        next_page = getattr(self, "next_page")
        try:
            value = self.use_selector(next_page)
        except (AttributeNotFound, XPathNotFound):
            return

        if value is None:
            return

        raise NextPage(value)

    def store(self, obj):
        if obj.id:
            if obj.id in self.objects:
                if self.ignore_duplicate:
                    self.logger.warning("There are two objects with the same ID! %s" % obj.id)
                    return
                else:
                    raise DataError("There are two objects with the same ID! %s" % obj.id)
            self.objects[obj.id] = obj
        return obj
Beispiel #18
0
 def __init__(self, *args, **kwargs):
     super(ListElement, self).__init__(*args, **kwargs)
     self.logger = getLogger(self.__class__.__name__.lower())
     self.objects = OrderedDict()
Beispiel #19
0
class Event(object):
    def __init__(self, name, backend):
        self.my_id = backend.browser.get_userid()
        self.name = "wiki/weboob/%s" % name
        self.description = None
        self.date = None
        self.begin = None
        self.end = None
        self.location = None
        self.winner = None
        self.backend = backend
        self.members = OrderedDict()
        self.load()

    def get_me(self):
        return self.members.get(self.backend.browser.get_userid(), None)

    def currently_in_event(self):
        if not self.date or not self.begin or not self.end:
            return False

        return self.begin < datetime.now() < self.end

    def is_closed(self):
        return self.end < datetime.now()

    def format_duration(self):
        if not self.begin or not self.end:
            return None

        delta = self.end - self.begin
        return "%02d:%02d" % (delta.seconds / 3600, delta.seconds % 3600)

    def check_time_coherence(self):
        """
        Check if the end's day is before the begin's one, in
        case it stops at the next day (eg. 15h->1h).

        If it occures, add a day.
        """
        if self.begin > self.end:
            self.end = self.end + timedelta(1)

    def load(self):
        self.content = self.backend.get_content(self.name)
        self.members.clear()
        member = None
        for line in self.content.content.split("\n"):
            line = line.strip()
            if line.startswith("h1. "):
                self.title = line[4:]
            elif line.startswith("h3=. "):
                m = re.match('h3=. Event finished. Winner is "(.*)":/users/(\d+)\!', line)
                if not m:
                    print >> sys.stderr, "Unable to parse h3=: %s" % line
                    continue
                self.winner = Member(int(m.group(2)), m.group(1))
            elif line.startswith("h2. "):
                continue
            elif line.startswith("h3. "):
                m = re.match('h3. "(.*)":/users/(\d+)', line)
                if not m:
                    print >> sys.stderr, 'Unable to parse user "%s"' % line
                    continue
                member = Member(int(m.group(2)), m.group(1))
                if member.id == self.my_id:
                    member.is_me = True
                if self.winner is not None and member.id == self.winner.id:
                    self.winner = member
                self.members[member.id] = member
            elif self.description is None and len(line) > 0 and line != "{{TOC}}":
                self.description = line
            elif line.startswith("* "):
                m = re.match("\* \*(\w+)\*: (.*)", line)
                if not m:
                    continue
                key, value = m.group(1), m.group(2)
                if member is None:
                    if key == "Date":
                        self.date = self.parse_date(value)
                    elif key == "Start" or key == "Begin":
                        self.begin = self.parse_time(value)
                    elif key == "End":
                        self.end = self.parse_time(value)
                        self.check_time_coherence()
                    elif key == "Location":
                        self.location = value
                else:
                    if key == "Repository":
                        m = re.match('"(.*.git)":.*', value)
                        if m:
                            member.repository = m.group(1)
                        else:
                            member.repository = value
                    elif key == "Hardware":
                        member.hardware = value
                    elif key == "Availabilities":
                        member.availabilities = value
            elif line.startswith("[["):
                m = re.match("\[\[(\w+)\]\]\|\[\[(\w+)\]\]\|(.*)\|", line)
                if not m:
                    print >> sys.stderr, 'Unable to parse task: "%s"' % line
                    continue
                task = Task(m.group(1), m.group(2))
                member.tasks.append(task)
                if m.group(3) == "!/img/weboob/_progress.png!":
                    task.status = task.STATUS_PROGRESS
                    continue

                mm = re.match("!/img/weboob/_done.png! (\d+):(\d+) (\w+)", m.group(3))
                if mm and self.date:
                    task.status = task.STATUS_DONE
                    task.date = datetime(
                        self.date.year, self.date.month, self.date.day, int(mm.group(1)), int(mm.group(2))
                    )
                    task.branch = mm.group(3)

    def parse_date(self, value):
        try:
            return datetime.strptime(value, "%Y-%m-%d")
        except ValueError:
            return None

    def parse_time(self, value):
        m = re.match("(\d+):(\d+)", value)
        if not m:
            return

        try:
            return self.date.replace(hour=int(m.group(1)), minute=int(m.group(2)))
        except ValueError:
            return None

    def save(self, message):
        if self.winner:
            finished = u'\nh3=. Event finished. Winner is "%s":/users/%d!\n' % (self.winner.name, self.winner.id)
        else:
            finished = u""
        s = u"""h1. %s

{{TOC}}
%s
h2. Event

%s

* *Date*: %s
* *Begin*: %s
* *End*: %s
* *Duration*: %s
* *Location*: %s

h2. Attendees

""" % (
            self.title,
            finished,
            self.description,
            self.date.strftime("%Y-%m-%d") if self.date else "_Unknown_",
            self.begin.strftime("%H:%M") if self.begin else "_Unknown_",
            self.end.strftime("%H:%M") if self.end else "_Unknown_",
            self.format_duration() or "_Unknown_",
            self.location or "_Unknown_",
        )

        for member in self.members.itervalues():
            if self.date:
                availabilities = ""
            else:
                availabilities = "* *Availabilities*: %s" % member.availabilities
            if member.repository is None:
                repository = "_Unknown_"
            elif member.repository.endswith(".git"):
                repository = '"%s":git://git.symlink.me/pub/%s ("http":http://git.symlink.me/?p=%s;a=summary)'
                repository = repository.replace("%s", member.repository)
            else:
                repository = member.repository

            s += u"""h3. "%s":/users/%d

* *Repository*: %s
* *Hardware*: %s
%s

|_.Backend|_.Capabilities|_.Status|""" % (
                member.name,
                member.id,
                repository,
                member.hardware,
                availabilities,
            )

            for task in member.tasks:
                if task.status == task.STATUS_DONE:
                    status = "!/img/weboob/_done.png! %02d:%02d %s" % (task.date.hour, task.date.minute, task.branch)
                elif task.status == task.STATUS_PROGRESS:
                    status = "!/img/weboob/_progress.png!"
                else:
                    status = " "
                s += u"""
|=.!/img/weboob/%s.png!:/projects/weboob/wiki/%s
[[%s]]|[[%s]]|%s|""" % (
                    task.backend.lower(),
                    task.backend,
                    task.backend,
                    task.capability,
                    status,
                )
            s += "\n\n"

        self.content.content = s
        self.backend.push_content(self.content, message)