Changeset 105
- Timestamp:
- 04/20/08 23:59:38 (7 months ago)
- Files:
-
- trunk/tracforums/__init__.py (modified) (1 diff)
- trunk/tracforums/htdocs/css/forums.css (modified) (2 diffs)
- trunk/tracforums/macros.py (modified) (9 diffs)
- trunk/tracforums/models/avatar.py (modified) (2 diffs)
- trunk/tracforums/models/category.py (modified) (1 diff)
- trunk/tracforums/models/forum.py (modified) (6 diffs)
- trunk/tracforums/models/main.py (modified) (4 diffs)
- trunk/tracforums/models/message.py (modified) (8 diffs)
- trunk/tracforums/models/profile.py (modified) (4 diffs)
- trunk/tracforums/models/topic.py (modified) (11 diffs)
- trunk/tracforums/orm.py (modified) (19 diffs)
- trunk/tracforums/templates/tracforums/_defs.cs (added)
- trunk/tracforums/templates/tracforums/header.cs (modified) (1 diff)
- trunk/tracforums/templates/tracforums/macro/embedreplies.cs (modified) (1 diff)
- trunk/tracforums/templates/tracforums/macro/recenttopics.cs (modified) (1 diff)
- trunk/tracforums/templates/tracforums/macro/recenttopicssummary.cs (modified) (1 diff)
- trunk/tracforums/templates/tracforums/message/_defs.cs (modified) (1 diff)
- trunk/tracforums/templates/tracforums/message/edit.cs (modified) (1 diff)
- trunk/tracforums/templates/tracforums/message/wiki.cs (added)
- trunk/tracforums/templates/tracforums/profile/_defs.cs (modified) (2 diffs)
- trunk/tracforums/templates/tracforums/topic/edit.cs (modified) (1 diff)
- trunk/tracforums/templates/tracforums/topic/view.cs (modified) (2 diffs)
- trunk/tracforums/web_ui.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/tracforums/__init__.py
r60 r105 2 2 from tracforums.web_ui import * 3 3 from tracforums.macros import * 4 from tracforums.search import * 5 from tracforums.timeline import * trunk/tracforums/htdocs/css/forums.css
r104 r105 176 176 } 177 177 178 .signature{ 179 border-top: 1px solid #D7D7D7; 180 } 181 178 182 label{ 179 183 width: 10em; … … 269 273 white-space: nowrap; 270 274 } 275 276 /** Macro Styles **/ 277 .embedded-reply{ 278 border: 1px solid rgb(0, 0, 0); 279 padding: 4px; 280 background: rgb(238, 238, 238) none repeat scroll 0%; 281 text-align: right; 282 } 283 284 .embedded-reply-date{ 285 float: left; 286 margin-top: 8px; 287 margin-left: 8px; 288 } 289 290 .embedded-reply img, 291 .reply-portrait{ 292 height: 32px; 293 float: right; 294 margin-left: 4px; 295 } 296 297 .embedded-reply-content{ 298 padding: 4px 4px 8px; 299 background: rgb(250, 250, 250) none repeat scroll 0%; 300 } 301 302 .recent-topics{ 303 margin-bottom: 5px; 304 } 305 306 .recent-topics .title{ 307 white-space: nowrap; 308 } 309 310 .recent-topics .synopsis{ 311 font-size: smaller; 312 font-style: italic; 313 } trunk/tracforums/macros.py
r104 r105 104 104 105 105 def __str__(self): 106 result = "TOKENS (" + str(len(self.tokens)) + "):\n"107 106 for tok in self.tokens: 108 107 result = result + str(tok) + "\n" … … 129 128 130 129 tokens = Tokenizer(content) 131 132 print tokens 133 130 134 131 def parseErr(tok,msg): 135 132 raise TracError("Macro Arguments " + str(tok.loc) + " at '" + str(tok.val) + "': " + msg) … … 228 225 Displays topics from a given forum. 229 226 230 RecentTopics(forum,maxposts=10 )227 RecentTopics(forum,maxposts=10,viewMoreText='View Older Topics...') 231 228 232 229 Example: 233 230 {{{ 234 231 [[RecentTopics('Test Forum')]] 235 }}} 232 }}} 236 233 """ 237 234 … … 240 237 args = parseMacroArgs( 241 238 content, 242 ["forum", "maxPosts"],243 [None , 10]239 ["forum", "maxPosts","viewMoreText"], 240 [None , 10 ,'View Older Topics'] 244 241 ) 245 242 … … 254 251 try: 255 252 from tracforums.models.forum import ForumModel 256 forum = ForumModel(db,context).load({"name":args.forum} ,debug=True)253 forum = ForumModel(db,context).load({"name":args.forum}) 257 254 except: 258 255 raise TracError("cannot find forum: '" + args.forum + "'") … … 274 271 req.hdf["forums"] = { 275 272 "forum": forum, 276 "topics": topics 273 "topics": topics, 274 "viewMoreText": args.viewMoreText, 277 275 } 278 276 req.hdf['trac.href.forums'] = self.env.href.forums() … … 292 290 Displays topics from a given forum 293 291 294 RecentTopicsSummary(forum,maxposts=10 )292 RecentTopicsSummary(forum,maxposts=10,viewMoreText='View Older Topics...') 295 293 296 294 Example: … … 304 302 args = parseMacroArgs( 305 303 content, 306 ["forum", "maxPosts"],307 [None , 10]304 ["forum", "maxPosts","viewMoreText"], 305 [None , 10 ,'View Older Topics'] 308 306 ) 309 307 … … 338 336 req.hdf["forums"] = { 339 337 "forum": forum, 340 "topics": topics 338 "topics": topics, 339 "viewMoreText": args.viewMoreText, 341 340 } 342 341 req.hdf['trac.href.forums'] = self.env.href.forums() trunk/tracforums/models/avatar.py
r102 r105 15 15 columns = { 16 16 "id": ORMKey(type='int', auto_increment = True), 17 "username": ORMColumn( ),18 "mimetype": ORMColumn( ),19 "name": ORMColumn( ),20 "avatarid": ORMAlias( sql="id"),17 "username": ORMColumn(type="str"), 18 "mimetype": ORMColumn(type="str"), 19 "name": ORMColumn(type="str"), 20 "avatarid": ORMAlias(type="int",sql="id"), 21 21 } 22 22 )): … … 94 94 # check if the file has been uploaded 95 95 if "filedata" in self.__dict__: 96 print "FILE:",self.filedata97 96 metrics = self.formatContext.getAvatarMetrics() 98 97 trunk/tracforums/models/category.py
r97 r105 53 53 "forums": ORMRelation( 54 54 model = ORMImportModel("tracforums.models.forum","ForumModelWithRecentPost"), 55 relationship = {"categoryid":"categoryid"} 55 relationship = {"categoryid":"categoryid"}, 56 debug = True 56 57 ), 57 58 } trunk/tracforums/models/forum.py
r104 r105 146 146 147 147 def saveModerators(self): 148 print "\nMODERATORS:",map(lambda x: x.username,self.moderators)149 148 if self.moderators and len(self.moderators) > 0: 150 149 from tracforums.models.moderator import ModeratorModel … … 166 165 # increase rank value to lower it's priority in the list 167 166 ranks = self.getColumnValues("rank",{"projectid":self.projectid,"categoryid":self.categoryid}) 168 print "\nRanks:",ranks169 167 idx = ranks.index(self.rank) 170 168 … … 177 175 # decrease rank value to raise it's priority in the list 178 176 ranks = self.getColumnValues("rank",{"projectid":self.projectid,"categoryid":self.categoryid}) 179 print "\nRanks:",ranks180 177 idx = ranks.index(self.rank) 181 178 … … 208 205 def doView(self): 209 206 args = self.getArgs() 210 forum = ForumModel(self.db,self).load({"id": args["viewid"]} ,debug=True)207 forum = ForumModel(self.db,self).load({"id": args["viewid"]}) 211 208 212 209 self.assertAction( … … 286 283 forum.attemptSave() 287 284 elif action == "save": 288 #print "SAVING..."289 285 forum.save() 290 286 self.db.commit() … … 292 288 except ModelValidateException,e: 293 289 validateErrors = e.reasons 294 295 print "\nforum:",forum 296 290 297 291 return { 298 292 "returnto": args.get("returnto",None), trunk/tracforums/models/main.py
r104 r105 42 42 from tracforums.models.category import CategoryModelWithForums 43 43 from tracforums.models.watch import ProjectWatchModelWithProfile 44 44 45 45 #filter visibiltiy for security 46 46 categoriesWithForums = [] … … 52 52 category.forums = categoryForums 53 53 categoriesWithForums.append(category) 54 55 #filter visibiltiy for security 56 54 57 55 return { 58 56 "returnto": self.req.abs_href.forums() + "main/index", … … 89 87 90 88 forum = ForumModel(self.db,self).load({"id":forumid}) 91 print "loaded forum:",forum92 89 if action == "category": 93 90 categoryid = int(categoryid) … … 228 225 "text/html": "main/profiles.cs" 229 226 }) 230 def doProfiles(self): 231 self.assertAction( 232 self.isForumUser(), 233 "You do not have permission to view this item." 234 ) 235 227 def doProfiles(self): 236 228 from tracforums.models.profile import ProfileModelWithAvatar 237 229 trunk/tracforums/models/message.py
r102 r105 43 43 type="datetime" 44 44 ), 45 46 47 "modifieddatehtml": ORMAlias( 48 name="modified", 49 type="date" 50 ), 51 52 "canEdit": ORMAlias(type="bool",sql=""" 53 %%(isadmin)s 54 or %(message)s.author = %%(authname)s 55 or ( 56 %%(isuser)s 57 and coalesce(( 58 select true from %(moderator)s m 59 join %(forum)s f on m.forumid = f.id 60 join %(topic)s t on f.id = t.forumid 61 where t.id = %(message)s.topicid and m.username=%%(authname)s 62 ),false) 63 ) 64 """ % Tablenames), 45 65 } 46 66 )): … … 59 79 60 80 def setTopic(self,topicModel): 61 self.topic = topicModel 62 self.topicid = topicModel.id 63 self.canModify = toBool(self._canModify()) 64 self.canView = toBool(self._canView()) 81 if topicModel != None: 82 self.topic = topicModel 83 self.topicid = topicModel.id 84 self.canModify = toBool(self._canModify()) 85 self.canView = toBool(self._canView()) 65 86 66 87 def setAuthor(self,profileModel): … … 90 111 base = MessageModel, 91 112 columns={ 92 "profile": ORMJoin(93 model = ORMImportModel("tracforums.models.profile","ProfileModelWithAvatar"),94 relationship = {"author":"profileid"}95 ),113 "profile": ORMJoin( 114 model = ORMImportModel("tracforums.models.profile","ProfileModelWithAvatar"), 115 relationship = {"author":"profileid"} 116 ), 96 117 "avatar": ORMJoin( 97 118 model = ORMImportModel("tracforums.models.avatar","AvatarModel"), … … 104 125 class MessageModelWithProfileAndTopic(ORMSchema( 105 126 base = MessageModelWithProfile, 106 columns={ 127 columns={ 107 128 "topic": ORMRelation( 108 129 model = ORMImportModel("tracforums.models.topic","TopicModelWithForum"), … … 114 135 self.setTopic(self.topic) 115 136 MessageModelWithProfile.format(self) 137 116 138 117 139 class MessageController(Controller): … … 123 145 }) 124 146 def doEdit(self): 147 return self.doEditImpl() 148 149 @PageHandler(["wiki"],{ 150 "text/html": "message/wiki.cs" 151 }) 152 def doWikiEdit(self): 153 return self.doEditImpl() 154 155 def doEditImpl(self): 125 156 args = self.getArgs() 126 157 message = MessageModel(self.db,self) 127 158 128 if args.get("messageid",0) != 0: 159 from tracforums.models.topic import TopicModelWithForum 160 from tracforums.models.profile import ProfileModelWithAssets 161 from tracforums.models.avatar import AvatarModel 162 163 if args.get("viewid",0) != 0: 164 #edit/modify the current message 129 165 message.load({"messageid": args["viewid"]}) 166 167 self.assertAction( 168 message.canEdit, 169 "You do not have permission to edit this item." 170 ) 171 message.modcount = message.modcount + 1 172 message.modifiedby = self.getAuthname() 173 message.modified = self.epochNow() 174 message.setTopic(TopicModelWithForum(self.db,self).load({"topicid":message.topicid})) 130 175 else: 131 from tracforums.models.topic import TopicModelWithForum 132 133 message.setTopic(TopicModelWithForum(self.db,self).load({"topicid":args["topicid"]})) 134 135 from tracforums.models.profile import ProfileModelWithAssets 136 authorProfile = ProfileModelWithAssets(self.db,self).load({"profileid":self.getAuthname()}) 137 authorProfile.posts = authorProfile.posts + 1 138 message.setAuthor(authorProfile) 139 140 validateErrors = [] 141 142 print "Profile: ",authorProfile,"\n" 143 176 # prep the model for a first time edit 177 message.setTopic(TopicModelWithForum(self.db,self).load({"topicid":args["topicid"]})) 178 179 # generic setup 180 message.profile = ProfileModelWithAssets(self.db,self).load({"profileid":message.author}) 181 message.profile.posts = message.profile.posts + 1 182 144 183 self.assertAction( 145 message != None, 146 "Topic does not exist" 147 ) 148 149 self.assertAction( 150 message.canModify, 184 message.topic.canAppend, 151 185 "You do not have permission to edit this item." 152 186 ) 153 187 188 validateErrors = [] 154 189 preview = False 155 190 … … 161 196 message.set(args) 162 197 message.doFormat() 163 if action == "preview": 164 #match avatar with message 165 for x in authorProfile.avatars: 166 if x.id == message.avatarid: 167 message.avatar = x 168 message.avatarid = x.id 198 if action == "preview": 169 199 preview = True 170 200 elif action == "save": 171 message.modcount = message.modcount + 1 172 authorProfile.save() 201 message.profile.save() 173 202 message.save() 174 203 self.db.commit() … … 177 206 validateErrors = e.reasons 178 207 179 from tracforums.models.avatar import AvatarModel180 from tracforums.models.message import MessageModelWithProfile208 # set the avatar after the post input has been accounted for 209 message.avatar = AvatarModel(self.db,self).load({"avatarid":message.avatarid}) 181 210 182 211 #Admins, original authors or new authors can change avatar trunk/tracforums/models/profile.py
r102 r105 45 45 if uiContext.isForumAdmin(): 46 46 self.canModify = True 47 elif uiContext.isForumUser() and uiContext.getAuthname() == instance['username']:47 elif uiContext.isForumUser() and uiContext.getAuthname() == self.username: 48 48 self.canModify = True 49 49 else: … … 90 90 orderby = [("profileid","asc")], 91 91 columns = { 92 "sightml": ORMAlias( 93 sql="sig", 94 type="wiki" 95 ), 92 96 "defaultAvatar": ORMJoin( 93 97 model = ORMImportModel("tracforums.models.avatar","AvatarModel"), 94 98 relationship = {"defaultavatarid":"id"} 95 ), 99 ), 96 100 } 97 101 ) … … 109 113 type="wiki" 110 114 ), 111 "sightml": ORMAlias( 115 } 116 ) 117 118 SearchableProfileModel = ORMSchema( 119 base = ProfileModel, 120 orderby = [("lastvisit","desc")], 121 columns = { 122 "biosynopsis": ORMAlias( 123 name="bio", 124 type="shortwiki" 125 ), 126 "sigsynopsis": ORMAlias( 112 127 name="sig", 113 type=" wiki"128 type="shortwiki" 114 129 ), 115 130 } 116 ) 131 ) 117 132 118 133 … … 144 159 145 160 profile = ProfileModelWithAssets(self.db,self).load({"profileid": args["viewid"]}) 146 print profile147 161 148 162 from tracforums.models.project import ProjectModel trunk/tracforums/models/topic.py
r104 r105 65 65 66 66 "canModify": ORMAlias(type="bool",sql=""" 67 %%(isadmin)s or 68 not (select locked from %(forum)s f where f.id = %(topic)s.forumid) 67 %%(isadmin)s 69 68 or ( 70 69 %%(isuser)s 71 70 and coalesce((select true from %(moderator)s m where m.forumid = %(topic)s.forumid and m.username=%%(authname)s),false) 71 ) 72 """ % Tablenames), 73 74 "canAppend": ORMAlias(type="bool",sql=""" 75 %%(isadmin)s or 76 ( 77 %%(isuser)s 78 and ( 79 coalesce((select true from %(moderator)s m where m.forumid = %(topic)s.forumid and m.username=%%(authname)s),false) 80 or not (select locked from %(forum)s f where f.id = %(topic)s.forumid) 81 ) 72 82 ) 73 83 """ % Tablenames), … … 103 113 def validateCreate(self): 104 114 return self.validate() 105 115 106 116 def validateSave(self): 107 117 return self.validate() 108 118 119 def touch(self): 120 if self.views == None: 121 self.views = 1 122 else: 123 self.views = self.views + 1 124 self.getBase().save(self) 125 109 126 def save(self,data={}): 127 TouchedTopicModel(self.db,self.formatContext).deleteMany({"topicid":self.id}) 110 128 self.getBase().save(self,data) 111 129 112 def saveAndNotify(self,data={}): 113 self.save(data) 130 def saveAndNotify(self,data={}): 114 131 from tracforums.models.watch import notifyTopicChanged 115 132 notifyTopicChanged(self.db,self.formatContext,self) 133 self.save(data) 116 134 117 135 … … 139 157 140 158 def format(self): 141 self.canAppend = toBool(self._canAppend())142 159 pass 160 143 161 def setForum(self,forumModel): 144 162 self.forum = forumModel 145 163 self.format() 146 147 def _canAppend(self):148 if not self.formatContext.isForumUser(): return False149 elif self.formatContext.isForumAdmin(): return True150 elif self.forum.locked: return False151 elif self.formatContext.getAuthname() == self.leadMessageAuthor: return True152 else: self.formatContext.getAuthname() in self.forum.moderators153 164 154 165 class TopicModelWithRecentPost(ORMSchema( … … 227 238 watchModel.save(criteria) 228 239 else: 229 if topic.views == None: 230 topic.views = 1 231 else: 232 topic.views = topic.views + 1 233 topic.save() 240 topic.touch() 234 241 235 242 #force changes through before display … … 252 259 "messageid": ("<>",topic.leadmessageid) 253 260 }), 261 "isForumUser": self.isForumUser(), 254 262 "watching": TopicWatchModelWithProfile(self.db,self).getMany({"topicid": topic.id}) 255 263 } … … 265 273 from tracforums.models.avatar import AvatarModel 266 274 from tracforums.models.forum import ForumModel 267 from tracforums.models.profile import ProfileModel 268 275 from tracforums.models.profile import ProfileModel, ProfileModelWithAssets 276 277 # edit existing model 269 278 if args.get("viewid",0) != 0: 270 279 topic.load({"topicid": args["viewid"]}) 271 topic.leadmessage = MessageModel(self.db,self).load({"id":topic.leadmessageid},debug=True) 272 messageAuthor = topic.leadmessage.author 280 topic.leadmessage = MessageModel(self.db,self).load({"messageid":topic.leadmessageid}) 281 282 self.assertAction( 283 topic.canModify, 284 "You do not have permission to view this item." 285 ) 286 287 # edit new model 273 288 else: 274 289 topic.doFormat() 275 290 #HACK: work around ORM limitations by loading up a dummy message model and forum 276 291 topic.leadmessage = MessageModel(self.db,self) 292 topic.leadmessage.author = self.getAuthname() 293 277 294 topic.setForum(ForumModel(self.db,self).load({"forumid":args["forumid"]})) 278 messageAuthor = self.getAuthname() 295 296 self.assertAction( 297 topic.forum.canAppend, 298 "You do not have permission to perform this action." 299 ) 300 301 topic.leadmessage.profile = ProfileModelWithAssets(self.db,self).load({"profileid":self.getAuthname()}) 302 topic.leadmessage.avatar = AvatarModel(self.db,self).load({"avatarid":topic.leadmessage.avatarid}) 303 279 304 validateErrors = [] 280 281 self.assertAction( 282 topic != None, 283 "Topic does not exist" 284 ) 285 286 self.assertAction( 287 topic.canModify, 288 "You do not have permission to view this item." 289 ) 290 291 preview = None 292 305 preview = None 306 293 307 if "action" in args: 294 308 action = args["action"] … … 298 312 topic.set(args) 299 313 topic.doFormat() 300 #hack: further work around ORM limitations by setting message parts directly301 #topic.leadmessage.body = args.get("body","")302 #topic.leadmessage.avatarid = args.get("avatarid",0)303 314 topic.leadmessage.set(args) 304 315 topic.leadmessage.created = self.epochNow() 305 316 topic.leadmessage.modified = self.epochNow() 306 topic.leadmessage.author = messageAuthor307 topic.leadmessage.profile = ProfileModel(self.db,self).load({"username":messageAuthor})308 317 topic.leadmessage.doFormat() 309 318 if action == "preview": 310 319 topic.attemptSave() 320 if topic.avatarid != 0: 321 topic.leadmessage.avatar = AvatarModel(self.db,self).load({"id":topic.avatarid}) 311 322 preview = [topic] 312 323 elif action == "save": … … 329 340 "topic": topic, 330 341 "preview": preview, 331 " avatars": AvatarModel(self.db,self).getMany({"username":messageAuthor}),342 "canSetAvatar": True, 332 343 "message_body_rows": self.getSessionVar("message_body_rows",8), 333 344 "validateErrors": validateErrors … … 359 370 "username": self.getAuthname(), 360 371 "topicid": topic.id 361 }) 372 }) 362 373 #force changes through before display 363 374 self.db.commit() … … 369 380 from tracforums.models.forum import ForumModel 370 381 371 return ("topic/manage.cs",{382 return { 372 383 "returnto": self.req.abs_href.forums() + "/topic/view/" + str(topic.id), 373 384 "validateErrors": validateErrors, … … 380 391 "topics": TopicModelWithForum(self.db,self).getMany(), #TODO: restrict to this project 381 392 "canMoveMessages": self.isForumAdmin() 382 } )393 } trunk/tracforums/orm.py
r104 r105 12 12 13 13 ### SQL Builder #### 14 15 def resolveOperator(op): 16 if not op in ["=","<",">","<=",">=","<>","like"]: return "=" 17 elif op == "like": 18 val = db.like_escape(val) 19 return db.like() 14 15 class AND: 16 def __init__(self,*terms): 17 self.terms = terms 18 19 class OR: 20 def __init__(self,*terms): 21 self.terms = terms 22 23 def getSqlTerm(db,part,prefix="",parentKey="",suffix=""): 24 termSQL = "" 25 termValues = {} 26 27 def getSqlSequence(terms,joinValue): 28 codeParts = [] 29 termValues = {} 30 i = 0 31 for x in terms: 32 (code,values) = getSqlTerm(db,x,prefix,parentKey,str(i)) 33 codeParts.append(code) 34 termValues.update(values) 35 i = i + 1 36 return(joinValue.join(codeParts),termValues) 37 38 if isinstance(part,AND): 39 (termSQL,termValues) = getSqlSequence(part.terms," and ") 40 41 elif isinstance(part,OR): 42 (termSQL,termValues) = getSqlSequence(part.terms," or ") 43 44 elif isinstance(part,tuple): 45 if len(part) == 1: 46 name = parentKey 47 op = "=" 48 (val) = part 49 if len(part) == 2: 50 name = parentKey 51 (op,val) = part 52 else: 53 (name,op,val) = part 54 lookup = prefix+name+suffix 55 if not op in ["=","<",">","<=",">=","<>","like"]: op = "=" 56 57 if isinstance(val,list): 58 listterms = [] 59 for i in range(0,len(val)): 60 keyname = lookup + str(i) 61 if op == "like": 62 thisOp = db.like() % ("%(" + keyname + ")s") 63 termValues[keyname] ="%" + str(val[i]) + "%" 64 else: 65 thisOp = op + " %(" + keyname + ")s" 66 termValues[keyname] = val[i] 67 listterms.append(name + " " + thisOp) 68 termSQL += "(" + " or ".join(listterms) + ")" 69 else: 70 if op == "like": 71 op = db.like() % ("%(" + lookup + ")s") 72 val = "%" + str(val) + "%" 73 else: 74 op = op + " %(" + lookup + ")s" 75 (termSQL,termValues) = (name + " " + op,{lookup:val}) 76 77 elif isinstance(part,list): 78 listterms = [] 79 for i in range(0,len(part)): 80 keyname = prefix + parentKey + str(i) 81 termValues[keyname] = val[i] 82 listterms.append(parentKey + " = %(" + keyname + ")s") 83 termSQL += "(" + " or ".join(listterms) + ")" 84 85 elif isinstance(part,dict): 86 codeParts = [] 87 for key in part: 88 (code,values) = getSqlTerm(db,part[key],prefix,key) 89 codeParts.append(code) 90 termValues.update(values) 91 termSQL = " and ".join(codeParts) 92 20 93 else: 21 return op 22 23 def getSqlTerm(term,prefix=""): 24 """ 25 getSqlTerm - composes SQL where expressions based on input 26 27 term = tuple or array: the term is composed as a tuple containing an (name,operator,value) 28 sequence, or an (sql,value) sequence. 29 term = string: the term is inserted into the where clause literally 30 term = dict: the key/value pairs are composed into an "and" delimited sequence of equality 31 (=) operations. 32 33 returns a tuple containing sql code and a map of values 34 """ 35 if type(term) == dict: 36 termSQL = [] 37 termVal = {} 38 for key in term: 39 val = term[key] 40 if type(val) == tuple: 41 (op,val) = val 42 termSQL.append(key + " " + resolveOperator(op) + " %(" + prefix+key + ")s") 43 termVal[prefix+key] = val 44 elif type(val) == list: 45 # populate a list 46 listterms = [] 47 for x in val: 48 keyname = prefix + key + str(len(listterms)) 49 termVal[keyname] = x 50 listterms.append(key + " = %(" + keyname + ")s") 51 termSQL.append("(" + " or ".join(listterms) + ")") 52 else: 53 termSQL.append(key + " = %(" + prefix+key + ")s") 54 termVal[prefix+key] = val 55 return (" and ".join(termSQL),termVal) 56 57 if type(term) == str or len(term) == 1: 58 return (term,{}) 59 elif len(term) == 2: 60 return term 61 else: 62 (name,op,val) = term 63 return (name + " " + resolveOperator(op) + " %(" + prefix+name + ")s",{prefix+name:val}) 64 65 def getSqlSequence(separator,terms): 66 sqlParts = [] 67 data = {} 68 for term in terms: 69 (termSQL,valueDict) = getSqlTerm(term) 70 sqlParts.append("(" + termSQL + ")") 71 data.update(valueDict) 72 return (separator.join(sqlParts),data) 73 74 def AND(*terms): 75 return getSqlSequence(" and ",terms) 76 77 def OR(*terms): 78 return getSqlSequence(" or ",terms) 79 80 defaultQuery = ("",{}) 94 lookup = prefix+parentKey+suffix 95 (termSQL,termValues) = (parentKey + " = %(" + lookup + ")s",{lookup:part}) 96 97 return (termSQL,termValues) 98 99 defaultQuery = {} 81 100 82 101 ### HDF #### … … 94 113 return self.__dict__[name] 95 114 return None 96 115 97 116 #NOTE: needed for HDF support to work 98 117 def keys(self): … … 131 150 def wiki(formatContext,value): 132 151 return formatContext.wikiToHTML(value) 133 152 153 @staticmethod 154 def shortwiki(formatContext,value): 155 synopsisLength = formatContext.getSynopsisLength() 156 if value and len(value) > synopsisLength: 157 value = value[:synopsisLength] + "..." 158 return formatContext.wikiToOneLiner(value) 159 134 160 @staticmethod 135 161 def oneliner(formatContext,value): … … 156 182 @staticmethod 157 183 def int(formatContext,value): 158 #####print "CONVERTING: ",value,type(value)159 184 return int(value) 160 185 … … 258 283 259 284 def doFormat(self,value,obj): 260 ####print "ORMColumn loadaction: ",fieldname,col.formatter,type(col.formatter),obj.__dict__[fieldname]261 285 if value != None: 262 286 return self.formatter(obj.formatContext,value) … … 291 315 Represents one or more model instances that get attached to the model at load time. 292 316 """ 293 def __init__(self,model,relationship=None,columnname=None,limit=0, *args,**kwargs):317 def __init__(self,model,relationship=None,columnname=None,limit=0,debug=False,*args,**kwargs): 294 318 ORMColumn.__init__(self,*args,**kwargs) 295 319 self.model = model … … 297 321 self.columnname = columnname 298 322 self.limit = lim
