public
Description: A Google App Engine app for sharing information about radars that we've submitted.
Homepage: http://openradar.appspot.com
Clone URL: git://github.com/timburks/openradar.git
openradar / models.py
100644 121 lines (96 sloc) 4.216 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from google.appengine.ext import db
from google.appengine.ext import search
import datetime
 
class Secret(db.Model):
  name = db.StringProperty()
  value = db.StringProperty()
 
class Radar(search.SearchableModel):
  # This first set of properties are user-specified.
  # For flexibility and robustness, we represent them all as strings.
  number = db.StringProperty() # the Radar Problem ID (we need an int form of this)
  title = db.StringProperty()
  status = db.StringProperty() # Radar state
  resolved = db.StringProperty()
  user = db.UserProperty() # App Engine user who created this entry
  product = db.StringProperty()
  classification = db.StringProperty()
  reproducible = db.StringProperty()
  product_version = db.StringProperty()
  description = db.TextProperty() # problem description plus anything else.
  originated = db.StringProperty() # when the Radar was filed
 
  created = db.DateTimeProperty() # when the OpenRadar object was created
  # These remaining properties are managed by the OpenRadar web app.
  # They are automatically set when put() is called.
  # We will add more as needed to allow better performance or to simplify sorting and querying.
  modified = db.DateTimeProperty() # when the OpenRadar object was last modified
 
  def username(self):
    return self.user.nickname().split("@")[0]
 
  def put(self):
    self.modified = datetime.datetime.now()
    db.Model.put(self)
    
  def comments(self):
    return Comment.gql("WHERE radar = :1 AND is_reply_to = :2", self, None)
 
import markdown
md = markdown.Markdown()
 
class Comment(search.SearchableModel):
  user = db.UserProperty() # App Engine user who wrote the comment
  subject = db.StringProperty()
  body = db.TextProperty() # as markdown
  posted_at = db.DateTimeProperty()
  radar = db.ReferenceProperty(Radar)
  is_reply_to = db.SelfReferenceProperty()
  
  def __init__(self, *args, **kwargs):
    super(Comment, self).__init__(*args, **kwargs)
    if(not self.posted_at): self.posted_at = datetime.datetime.now()
    if(not self.body): self.body = ""
    if(not self.subject): self.subject = ""
    
  def username(self):
    return self.user.nickname().split("@")[0]
      
  def radar_exists(self):
    try:
      return self.radar != None
    except db.Error:
      return False
 
  def radarnumber(self):
    return self.radar_exists() and self.radar.number or "Deleted"
 
  def radartitle(self):
    return self.radar_exists() and self.radar.title or "Deleted"
 
  def replies(self):
    return Comment.gql("WHERE is_reply_to = :1", self)
  
  # I know this is a bad place to put it, but my only other idea is custom django template tags, and I just couldn't get those to work
  def draw(self, onlyInner = False):
    from google.appengine.ext.webapp import template
    import os
    directory = os.path.dirname(__file__)
    path = os.path.join(directory, os.path.join('templates', "comment.html"))
    
    return template.render(path, {"comment": self, "onlyInner": onlyInner})
  
  def form(self):
    from google.appengine.ext.webapp import template
    import os
    directory = os.path.dirname(__file__)
    path = os.path.join(directory, os.path.join('templates', "comment-form.html"))
    
    return template.render(path, {"comment": self})
  
  def html_body(self):
    return md.convert(self.body)
 
  def editable_by_current_user(self):
    from google.appengine.api import users
    user = users.GetCurrentUser()
    return user == self.user or users.is_current_user_admin()
    
  def deleteOrBlank(self):
    if self.replies().count() > 0:
      self.subject = "(Removed)"
      self.body = "*This comment has been removed by its author or a moderator.*"
      self.put()
      return "blanked"
    else:
      self.delete()
      return "deleted"
  
class Profile(db.Model):
  name = db.StringProperty() # screen name
  twitter = db.StringProperty() # twitter id
  user = db.UserProperty()
  radar_count = db.IntegerProperty()
  
class Bump(db.Model):
  radar = db.ReferenceProperty(Radar) # users can bump radars to raise their profile
  user = db.UserProperty() # the bumping user
  created = db.DateTimeProperty() # when the bump was added