Exemple #1
0
class Document(db.TimeStampedBase):
    owner = db.ForeignKey(kind=Member)
    logo = db.Binary()
    template = db.ForeignKey(kind=Template)
    name = db.String()
    injections = db.JSON()
    assembly = db.JSON()
    declarations = db.JSON()
    pdf = db.String()
    revision = db.Integer(default=0)
    signup_sheet = db.Boolean(default=True)
    table_of_contents = db.Boolean(default=True)
    declaration_page = db.Boolean(default=True)
    pretty_filenames = db.Boolean(default=True)
    section_page_breaks = db.Boolean(default=False)

    def summary(self):
        d = {
            "key": self.id(),
            "name": self.name,
            "revision": self.revision,
            "pdf": self.pdf,
            "created": str(self.created)[:19],
            "modified": str(self.modified)[:19],
            "declarations": self.declarations or {}
        }
        if self.template:
            t = self.template.get()
            d["template"] = {"key": t.id(), "name": t.name}
        return d

    def content(self, sections=None):
        return self.template.get().content(
            sections, page_breaks=self.section_page_breaks)
Exemple #2
0
class Contactable(db.TimeStampedBase):
    tags = db.ForeignKey(kind=Tag, repeated=True)
    member = db.ForeignKey()
    name = db.String()
    email = db.String()
    phone = db.String()
    address = db.String()
    description = db.Text()  # only required field
    closed = db.Boolean(default=False)
    ongoing = db.Boolean(default=False)
Exemple #3
0
class Expense(Verifiable):
    executor = db.ForeignKey(kind="Person")  # reimbursement only
    variety = db.String(choices=["dividend", "reimbursement"])
    amount = db.Float(default=0.1)  # for dividend, split amount * total
    recurring = db.Boolean(default=False)

    def dividend(self):
        pod = self.pod()
        pool = pod.pool.get()
        people = db.get_multi(pod.members())
        div = self.amount * pool.outstanding
        cut = div / len(people)
        for person in people:
            person.wallet.get().deposit(cut, pod, self, "dividend")
        pool.debit(div, pod, self, "dividend")

    # reimbursement requires $$ conversion...
    def reimbursement(self):
        pass

    def fulfill(self):
        if (self.passed and not self.recurring) or not self.verified():
            return False
        getattr(self, self.variety)()
        return True
Exemple #4
0
class Verifiable(db.TimeStampedBase):
    membership = db.ForeignKey(kind="Membership")
    passed = db.Boolean(default=False)
    notes = db.Text()

    def pod(self, noget=False):
        pod = self.membership.get().pod
        return noget and pod or pod.get()

    def signers(self):
        return self.pod().members()

    def fulfill(self):
        if not self.verified():
            return False
        self.passed = True
        self.put()
        return True

    def notify(self, subject, body, signers=None):
        for signer in (signers or self.signers()):
            if self.unverified(signer):
                send_mail(to=signer.get().email,
                          subject=subject,
                          body=body(signer))

    def unverify(self):
        log("unverifying %s" % (self.key.urlsafe(), ))
        sigs = Verification.query(Verification.act == self.key).fetch()
        log("unsigning %s verifications" % (len(sigs), ), 1)
        db.delete_multi(sigs)
        log("unpassing", 1)
        self.passed = False
        self.put()

    def verify(self, person):
        if person in self.signers():
            if Verification.query(Verification.act == self.key,
                                  Verification.person == person).get():
                return log("already verified (%s %s)!" % (self.key, person),
                           important=True)
            log("verification (%s %s) success" %
                (self.key.urlsafe(), person.urlsafe()))
            Verification(act=self.key, person=person).put()
            return self.fulfill()
        log("verification attempt (%s %s) failed -- unauthorized" %
            (self.key, person))

    def veriquery(self):
        return Verification.query(Verification.act == self.key)

    def unverified(self, person):
        return not self.veriquery().filter(Verification.person == person).get()

    def verified(self):
        for person in self.signers():
            if self.unverified(person):
                return False
        return True
Exemple #5
0
class Feedback(db.TimeStampedBase):
    person = db.ForeignKey(kind=Person)
    conversation = db.ForeignKey(kind=Conversation)
    interaction = db.ForeignKey(kinds=[Appointment, Delivery, Request])
    answers = db.ForeignKey(kind=Answer, repeated=True)
    topic = db.String()
    notes = db.Text()
    followup = db.Boolean(default=False)

    def membership(self):
        from .util import membership
        return membership(self.person.get(), self.pod())

    def pod(self):
        return self.interaction.get().pod()

    def full(self):
        answers = "\n\n".join([a.full() for a in db.get_multi(self.answers)])
        return "\n\n".join([
            self.topic, answers, self.notes,
            "request follow up: %s" % (self.followup, )
        ])

    def notify(self):
        bod = FEEDBACK % (self.person.get().firstName, self.pod().name,
                          self.full(), self.key.urlsafe())
        self.interaction.get().notify("feedback", lambda signer: bod,
                                      self.participants())

    def participants(self):
        pars = self.interaction.get().signers()
        if self.person not in pars:
            return pars + [self.person]
        return pars

    def oncreate(self):
        convo = Conversation(topic=self.topic)
        convo.participants = self.participants()
        convo.put()
        self.conversation = convo.key
        self.put()  # for notify() key
        self.notify()
        if self.followup:
            req = Request()
            req.membership = self.membership().key
            req.change = "conversation"
            req.notes = self.notes
            req.put()
            req.remind()
Exemple #6
0
class Section(SecBase):
    image = db.Binary()
    headerless = db.Boolean(default=False)

    def labeler(self):
        return "%s [%s]" % (self.name, self.index)

    def header(self):
        return self.headerless and " " or self.name

    def desc(self, depth=0, novars=False):
        d = self.fixed_desc(depth, novars)
        if not self.image:
            return d
        return "%s\r\n\r\n![](%s)" % (d, symage(self.image.path))
Exemple #7
0
class Board(db.TimeStampedBase):
    name = db.String()
    description = db.Text()
    anonymous = db.Boolean(default=False)
    tags = db.ForeignKey(kind=Tag, repeated=True)
    conversation = db.ForeignKey(kind=Conversation)
    label = "name"

    def pod(self):
        from .core import Pod
        return Pod.query(Pod.boards.contains(self.key.urlsafe())).get()

    def notify(self, podname, interested):
        bod = BOARD % (podname, self.name, self.description)
        for person in interested:
            send_mail(to=person.email, subject="new message board", body=bod)

    def oncreate(self):
        convo = Conversation(topic=self.name)
        convo.anonymous = self.anonymous
        convo.put()
        self.conversation = convo.key
Exemple #8
0
class Payment(db.TimeStampedBase):
    member = db.ForeignKey(kind=Member)
    successful = db.Boolean(default=False)
    amount = db.String()
    duration = db.Integer()  # days
    message = db.Text()
Exemple #9
0
class Person(Member):
    ip = db.String()  # optional
    wallet = db.ForeignKey(kind=Wallet)  # optional
    interests = db.ForeignKey(kind=Tag, repeated=True)
    contributors = db.ForeignKey(kind=Contributor, repeated=True)
    chat = db.Boolean(default=True)
    remind = db.Boolean(default=True)

    def onjoin(self):
        from .util import global_pod
        email_admins("New Person", self.email)
        self.enroll(global_pod())
        wallet = Wallet()
        wallet.put()
        self.wallet = wallet.key
        self.put()
        self.process_invites()

    def process_invites(self):
        log("processing invitations for %s" % (self.email, ))
        podz = set()
        for invitation in Invitation.query(
                Invitation.email == self.email).fetch():
            imem = invitation.membership.get()
            ipod = imem.pod.get().name
            memem = imem.person.get().email
            log("pod: %s. inviter: %s" % (ipod, memem), 1)
            if ipod in podz:
                log("skipping invitation -- already invited to pod", 2)
            else:
                log("sending invitation", 2)
                podz.add(ipod)
                invitation.send(self)

    def help_match(self,
                   item):  # overrides Member.help_match() in ctcoop.model
        from .util import membership, reg_act
        which = item.polytype
        isneed = which == "need"
        pod = Pod.query(
            getattr(Pod, which + "s").contains(item.key.urlsafe())).get()
        reg_act(
            membership(self, pod).key, pod.support_service(),
            [isneed and self.key or item.member],
            [isneed and item.member or self.key], item.description)

    def enroll(self, pod):
        from .util import membership
        memship = membership(self, pod)
        if not memship:
            memship = Membership(pod=pod.key, person=self.key)
            memship.put()
        return memship.key

    def tasks(self):
        return db.get_multi(sum([p.tasks for p in self.pods()], []))

    def pods(self):
        return db.get_multi([m.pod for m in self.memberships()])

    def memberships(self):
        return Membership.query(Membership.person == self.key).fetch()

    def acts(self):
        yesterday = datetime.now() - timedelta(1)
        return sum([
            Act.query(Act.membership == m.key,
                      Act.created > yesterday).fetch()
            for m in self.memberships()
        ], [])

    def commitments(self):
        return sum([
            Commitment.query(Commitment.membership == m.key).fetch()
            for m in self.memberships()
        ], [])
Exemple #10
0
class BasePost(db.TimeStampedBase):
    user = db.ForeignKey()  # CTUser, Author, or whatever else
    live = db.Boolean(default=False)
    title = db.String()
    blurb = db.String()
    tags = db.String(repeated=True)
Exemple #11
0
class Building(Place):
    year = db.Integer()
    building_id = db.String()
    building_type = db.String()
    owner = db.ForeignKey(kind="owner")
    rent_control = db.Boolean()