Exemplo n.º 1
0
class Foo(MonDoc):
    name = StrField()
    description = TextAreaField(monospaced=True)
    aNumber = IntField(minValue=0, maxValue=100)
    minSpeed = FloatField(title="Minimum Speed, mph", minValue=0.0)
    maxSpeed = FloatField(title="Maximim Speed, mph", minValue=0.0)
    favouriteDrink = ChoiceField(choices=DRINK_CHOICES,
                                 showNull=True,
                                 allowNull=True)
    fruitsLiked = MultiChoiceField(choices=FRUIT_CHOICES,
                                   desc="tick all fruits this person likes")
    tickyBox = BoolField()
    aDate = DateField()
    lastSaved = DateTimeField(desc="when this foo was last saved",
                              readOnly=True)
    aDateTime = DateTimeField(title="A Date and Time")
    anything = ObjectField(desc="can contain anything",
                           default=["any", "thing"])
    favouriteBook = FK(models.Book, allowNull=True, showNull=True)

    @classmethod
    def classLogo(self):
        return "<i class='fa fa-star-o'></i> "

    def formWideErrorMessage(self):
        if self.minSpeed > self.maxSpeed:
            return "Minimum speed cannot be greater than maximum speed"
        return ""  # no error message, validates OK

    def preSave(self):
        self.lastSaved = BzDateTime.now()
        d = self.mongoDict()
        d.pop('anything', "")  # remove the anything field
        dpr("d=%r", d)
        self.anything = d
Exemplo n.º 2
0
class Tag(MonDoc):
    _id = StrField(desc="tag id")
    created = DateTimeField(desc="when tag was created")
    lastUsed = DateTimeField(desc="when tag was most recently used")
    timesUsed = IntField(desc="number of times used")

    def getName(self) -> str:
        return "#" + self._id

    @classmethod
    def classLogo(cls) -> str:
        return "<i class='fa fa-hashtag'></i> "
Exemplo n.º 3
0
class Alert(MonDoc):
    user_id = FK(userdb.User, desc="who this alert is for")
    alertType = ChoiceField(choices=ALERT_TYPES,
                            desc="type of this alert",
                            allowNull=False,
                            readOnly=True)
    message_id = FK(Message, desc="the message this alert relates to")
    live = BoolField(default=True,
                     desc="an alert is live until the user clicks to view it")
    created = DateTimeField(desc="when this alert was created", readOnly=True)
    doer_id = FK(userdb.User, desc="user who starred/replied")
    reply_id = FK(Message, desc="the reply", allowNull=True)

    def logo(self):
        if self.live:
            return "<i class='fa fa-bell'></i> "
        else:
            return "<i class='fa fa-bell-o'></i> "

    @classmethod
    def classLogo(self):
        return "<i class='fa fa-bell-o'></i> "

    def preCreate(self):
        """ before saving, create the bioHtml """
        self.created = BzDateTime.now()
Exemplo n.º 4
0
class WikiPage(MonDoc):
    owner_id = FK('User', allowNull=False, desc="the owner of this wikipage")
    pageName = StrField(desc="page name")
    version = IntField(desc="version number")

    source = TextAreaField(monospaced=True, required=True)
    html = TextAreaField(monospaced=True, readOnly=True)
    published = DateTimeField(readOnly=True,
                              dateTimeFormat=models.MESS_TIME_DISPLAY_FORMAT)

    @classmethod
    def classLogo(cls) -> str:
        return "<i class='fa fa-file-text-o'></i> "

    def logo(self) -> str:
        return ("<i class='fa fa-home'></i> " if self.pageName == "home" else
                "<i class='fa fa-file-text-o'></i> ")

    def url(self) -> str:
        theUrl = form("/wiki/{u}/{pn}", u=self.owner_id, pn=self.pageName)
        return theUrl

    def getName(self) -> str:
        return self.pageName

    def preCreate(self):
        self.published = BzDateTime.now()

    def preSave(self):
        """ before saving, render the source into html """
        self.html, _ = mark.render(self.source, wikiExt=True)
Exemplo n.º 5
0
class UserDemographics(MonDoc):
    """ demographics of a user """
    
    _id = StrField(desc="User id", title="User Id",
        displayInForm=False,
        required=True, readOnly=True)
    
    decadeBorn = ChoiceField(
        desc="which decade were you born in",
        choices=DECADE_BORN_CHOICES,
        showNull=True, allowNull=False)
    religionBroughtUp = ChoiceField(
        desc="religion you were brought up in",
        choices=RELIGION_CHOICES,
        showNull=True, allowNull=False)
    religionNow = ChoiceField(
        desc="religion you are now",
        choices=RELIGION_CHOICES,
        showNull=True, allowNull=False)
    
    savedAt = DateTimeField(desc="when the data was saved",
        displayInForm=False,
        readOnly=True)
     
    @classmethod
    def classLogo(cls):
        return "<i class='fa fa-male'></i> "
Exemplo n.º 6
0
class WikiPage(MonDoc):
    _id = StrField(readOnly=True)
    owner_id = FK('User', allowNull=False,
        desc="the owner of this wikipage")
    folder = StrField(desc="path to folder")
    filename = StrField(desc="canonical filename (in folder)")
    version = IntField(desc="version number")
    
    source = TextAreaField(monospaced=True, required=True)
    html = TextAreaField(monospaced=True, readOnly=True)
    published = DateTimeField(readOnly=True,
        dateTimeFormat=models.MESS_TIME_DISPLAY_FORMAT)

    @classmethod
    def classLogo(cls) -> str:
        return "<i class='fa fa-file-text-o'></i> "
    
    def preCreate(self):
        self.published = BzDateTime.now()
        
    def canAlter(self, userName: str) -> bool:
        """ Can a user alter this wiki page? 
        At the moment only the owner of a apge can alter it.
        Later we will enable collaborative wikis.
        """
        return canAlter(userName, self.owner_id, self.folder, self.filename)
Exemplo n.º 7
0
class FileExample(MonDoc):
    name = StrField()
    description = TextAreaField()
    timestamp = DateTimeField(desc="when this filex was last altered",
        readOnly=True)
   
    @classmethod
    def classLogo(self):
        return "<i class='fa fa-file'></i> "
        
    def preSave(self):
        self.timestamp = BzDateTime.now()
Exemplo n.º 8
0
class WikiPage(MonDoc):
    _id = StrField(readOnly=True)
    owner_id = FK('User', allowNull=False, desc="the owner of this wikipage")
    folder = StrField(desc="path to folder")
    filename = StrField(desc="canonical filename (in folder)")
    version = IntField(desc="version number")

    source = TextAreaField(monospaced=True, required=True)
    html = TextAreaField(monospaced=True, readOnly=True)
    published = DateTimeField(readOnly=True,
                              dateTimeFormat=models.MESS_TIME_DISPLAY_FORMAT)

    @classmethod
    def classLogo(cls) -> str:
        return "<i class='fa fa-file-text-o'></i> "

    def preCreate(self):
        self.published = BzDateTime.now()
Exemplo n.º 9
0
class Answer(MonDoc):
    """ an answer by a user to a question 
    An answer can either be a string or an integer.
    If it is an integer, (ans) must be "" and ani is the answer
    If it is a string, ans cannot be "" and ani must be 0.
    """
    
    user_id = FK(userdb.User)
    question_id = StrField(desc="ID of question")
    savedAt = DateTimeField(desc="when the question was answered", 
        readOnly=True)
    ans = StrField(desc="the user's answer to the question, as a string") 
    ani = StrField(desc="the user's answer to the question, as an integer") 
 
    @classmethod
    def classLogo(cls):
        return "<i class='fa fa-check-square-o'></i> "
    
    def preSave(self):
        self.savedAt = BzDateTime.now()
Exemplo n.º 10
0
class Message(MonDoc):
    title = StrField(readOnly=True)
    source = TextAreaField(monospaced=True, required=True)
    html = TextAreaField(monospaced=True, readOnly=True)

    replyTo_id = FK('Message',
                    allowNull=True,
                    desc="the message this is a reply to")
    author_id = FK('User', allowNull=False, desc="the author of this message")
    tags = ObjectField()
    published = DateTimeField(readOnly=True,
                              dateTimeFormat=MESS_TIME_DISPLAY_FORMAT)
    starredBy_ids = FKeys('User')
    numStars = IntField(desc='number of stars on this message')

    @classmethod
    def classLogo(cls) -> str:
        return "<i class='fa fa-comment-o'></i> "

    def preCreate(self):
        self.published = BzDateTime.now()

    def preSave(self):
        """ before saving, create the title """
        lines = self.source.split("\n")
        if len(lines) >= 1:
            self.title = maxChars(lines[0], 80, 90)
        else:
            self.title = ""
        self.numStars = len(self.starredBy_ids)

    def url(self):
        u = "/mess/" + self.id()
        return u

    def fullUrl(self):
        return config.SITE_STUB + self.url()

    #========== display a message ==========

    def viewH(self) -> str:
        """ return HTML displaying this message """
        h = form(
            """
<div class='mess'>            
    <div class='mess-header'>
        {messLink}/{userLink} at {published}{replyToText}
    </div>
    {body}
    <p class='mess-footer'>
    {context}
    - <a href='/thread/{id}'>thread</a>
    - <a href='/messSource/{id}'>source</a>
    {reply}
    - {star}
    </p>
</div>""",
            id=self.id(),
            messLink=self.linkA(),
            userLink=self.author.blogLink(),
            replyToText=self.replyToText(),
            published=self.asReadableH('published'),
            body=self.html,
            context=self.contextA(),
            reply=self.replyA(),
            star=self.starH(),
        )
        return h

    def starH(self) -> str:
        """ The HTML for a star underneath a message """
        h = ""
        c = ""
        if self.numStars >= 1:
            h = form("{} ", self.numStars)
        cun = currentUserName()
        if not cun or cun == self.author_id:
            #>>>>> not logged in, or author
            h += "<i class='fa fa-star-o fa-lg'></i> "
        else:
            #>>>>> user is not message author
            # has this user starred the message?
            starred = cun in self.starredBy_ids
            if starred:
                h += "<i class='starred fa fa-star fa-lg'></i> "
                c = "starred"
            else:
                h += form(
                    """<i onclick='starClicked("{mid}")' """
                    "class='can_star fa fa-star-o fa-lg'></i> ",
                    mid=self._id)
                c = "can_star"
        #//if
        h2 = form("<span class='{c}'>{h}</span>", c=c, h=h)
        return h2

    def linkA(self) -> str:
        """ link to this message's /mess page """
        h = form("<a href='/mess/{id}'>{id}</a>", id=htmlEsc(self._id))
        return h

    def replyA(self) -> str:
        """ html containing the link to reply to this message.
        If not logged in this is empty.
        """
        cun = currentUserName()
        if not cun: return ""
        h = form("- <a href='/messRep/{id}'>reply</a> ", id=self.id())
        return h

    def replyToText(self) -> str:
        """ if this message is a reply, text in the header linking to the
        message it's a reply to. """
        if not self.replyTo_id: return ""
        parent = self.replyTo
        if not parent: return ""
        h = form(" reply-to: {messLink}/{userLink}",
                 messLink=parent.linkA(),
                 userLink=parent.author.blogLink())
        return h

    def contextA(self) -> str:
        """ if post is a reply, return html for link to context of post """
        if self.isHeadPost(): return ""
        h = form("- <a href='/context/{id}'>context</a>", id=self.id())
        return h

    def viewOneLine(self, showAuthor: bool = True) -> str:
        """ View this message as one line 
        @parasm showAuthor = if true, show the author of this message
        """
        publishedShort = self.asReadableH('published')[2:]
        title = self.asReadableH('title')
        authorA = ""
        if showAuthor:
            authorA = form("<a class='author' "
                           "href='/blog/{u}'>@{u}</a> ",
                           u=self.author_id)
        h = form(
            "<br>{publishedShort} "
            "{authorA}"
            "<a href='/mess/{id}'>{title}</a>\n",
            publishedShort=publishedShort,
            authorA=authorA,
            id=self.id(),
            title=title)
        return h

    #========== misc utility functions ==========

    def context(self) -> List['Message']:
        """ the list of messages leading up to this one, including this 
        one, in chronological order 
        """
        if self.isHeadPost(): return [self]
        parent = self.getParent()
        if parent:
            return parent.context() + [self]
        else:
            return [self]

    def isReply(self) -> bool:
        return bool(self.replyTo_id)

    def isHeadPost(self) -> bool:
        return not self.isReply()

    def getParent(self) -> Union['Message', None]:
        """ if a post has a parent, return it, else return None """
        if self.isHeadPost(): return None
        return Message.getDoc(self.replyTo_id)

    def getNumChildren(self) -> int:
        """ return the number of replies this message has """
        return Message.count({'replyTo_id': self._id})

    def getChildren(self):
        """ return an iterator to the message's replies (oldest first) 
        returns an Iterable[Message]
        """
        ms = Message.find({'replyTo_id': self._id}, sort='published')
        return ms