# -*- coding: utf-8 # Copyright 2006 by Meelis Mets, Vahur Rebas from Products.Archetypes.public import BaseSchema, Schema from Products.Archetypes.public import LinesField, DateTimeField, TextField, StringField, ComputedField from Products.Archetypes.public import MultiSelectionWidget, TextAreaWidget, StringWidget, ComputedWidget from Products.Archetypes.public import BaseContent, OrderedBaseFolder, registerType from Widgets import TagsWidget, TagsField, TrackbackWidget, TrackbacksMadeToWidget, TrackbackLinkWidget, DictField, HelpWidget, RichWidget from Globals import InitializeClass from Products.CMFCore.utils import getToolByName from AccessControl import ClassSecurityInfo, Unauthorized from Acquisition import aq_base, Explicit from config import PROJECT_NAME, BLOG_TYPES from Permissions import * import re schema = BaseSchema + Schema(( )) from Globals import Persistent, Acquisition from OFS.SimpleItem import Item class BlogRedirector(Persistent, Item, Explicit): """ redirector object """ meta_type = 'BlogRedirector' global_allow = False id = 'redirector' def __bobo_traverse__(self, REQUEST, entry_name): """ bobo """ stack = REQUEST.get('TraversalRequestNameStack') if not stack: entry_name = 'index_html' return getattr(self, entry_name) uid = '' if entry_name == 'trackback': uid = stack.pop() #print REQUEST.get('TraversalRequestNameStack'), uid REQUEST.set('uid', uid) return getattr(self, 'respond') def index_html(self, REQUEST): """ view method """ return "This is a special object, nothing to see here" def respond(self, REQUEST): """ respond with error_type and error_message """ # must have url. title, excerpt and blog_name are optional err_code = 0 # 1 - error # 0 - no error err_mess = '' redirect_to_object = False if REQUEST.get('REQUEST_METHOD').lower() != 'post': err_code = 2 err_mess = 'Invalid method' redirect_to_object = True obj = None if not err_code or redirect_to_object: rc = getToolByName(self.aq_parent, 'reference_catalog') if redirect_to_object: obj = rc.lookupObject(REQUEST.get('uid'), REQUEST) else: obj = rc.lookupObject(REQUEST.get('uid')) if not REQUEST.get('url', '') or not obj: err_code = 1 err_mess = 'invalid URL' if not err_code and obj: url = REQUEST.get('url', '') title = REQUEST.get('title', '') excerpt = REQUEST.get('excerpt', '') blog_name = REQUEST.get('blog_name', '') import akismet api = akismet.Akismet('04d8e92bdd53','http://eportfoolio.opetaja.ee',agent='Eportfolio 1.5') if api.key is None: print "No 'apikey.txt' file." elif not api.verify_key(): print "The API key is invalid." else: data = {} data['user_ip'] = url data['user_agent'] = '' data['comment_author_url'] = url if api.comment_check(title, data): err_code = 2 err_mess = 'This comment is spam' else: print "adding tracback to:", obj obj._addTrackback(url, title, excerpt, blog_name) REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml') return """%s%s""" % (err_code, err_mess) class BlogFolder(OrderedBaseFolder): """ Blog product """ meta_type = "BlogFolder" archetype_name = "BlogFolder" global_allow = 0 allowed_content_types = ('BlogEntry','BlogCategory') security = ClassSecurityInfo() schema = schema actions = ( { 'id':'view', 'name':'View', 'action':'string:${object_url}/blog_view', 'permissions': ('View',), }, { 'id':'edit', 'name':'Edit', 'action':'string:${object_url}/base_edit', 'permissions': ('Create Form',), }, { 'id':'metadata', 'name':'Properties', 'action':'string:${object_url}/base_metadata', 'permissions': ('Manage Portal',), }, ) def __init__(self, id): OrderedBaseFolder.__init__(self, id) self.id = id self.largeIcon = "blog.gif" # [['Kala', 'http://www.kala.ee'], ['Koll', 'http://www.koll.ee']] self.blogrolllinks = [] def RestrictItem(self, id, REQUEST, members='', groups=''): """ """ ObjId = self._getOb(id) # print ObjId allow = REQUEST.get('access', '') if allow == '': last = REQUEST.get('last_status', 'public') if last == 'public': status = 'publish' if last == 'hidden': status = 'hide' return self.REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+str(id)+'/restrict?last='+last) from config import TASK_TYPES viewers = ObjId.users_with_local_role('Viewer') # print viewers, '........' for v in viewers: ObjId.manage_delLocalRoles([v]) # print ObjId.users_with_local_role('Viewer'), ',,,,,,' ObjId.manage_permission(View, ('Manager','Owner','Viewer'), 0) ct = getToolByName(self, 'caching_tool') if str(allow) == 'teachers': print 'teachers' user = str(self.REQUEST.AUTHENTICATED_USER) user_groups = self.REQUEST.AUTHENTICATED_USER.getGroups() user_groups.append(user) pc = getToolByName(self, 'portal_catalog') res = pc({'portal_type':TASK_TYPES, 'getTarget':user_groups}) gt = getToolByName(self, 'portal_groups') allgroups = ct._getGroups() lect = [] addedGroups = [] for x in res: task = x.getObject() target = task.getLecturer() print target for t in target: addedLect = 0 for l in lect: #print '--', l, t, '--' if str(l) == str(t): addedLect = 1 if addedLect == 0: lectgroup = 0 for g in allgroups: print g if str(g) == t: addedGroups.append(g) #g_members = gt.getGroupMembers(g.id) g_members = ct._getGroupMembers(g) #print g_members for m in g_members: added = 0 for l in lect: if str(l) == str(m): added = 1 if added == 0: lect.append(m) lectgroup = 1 if lectgroup == 0: lect.append(t) # print lect for user in lect: # print user ObjId.manage_setLocalRoles(str(user),('Viewer',)) if str(allow) == 'groupmembers': if isinstance(members, type('')): members = [members,] for user in members: # print user ObjId.manage_setLocalRoles(str(user),('Viewer',)) if str(allow) == 'groups': if isinstance(groups, type('')): groups = [groups,] for group in groups: print group gt = getToolByName(self, 'portal_groups') groupObj = gt.getGroupById(group) #groupmembers = groupObj.getGroupMembers() groupmembers = ct._getGroupMembers(groupObj) for user in groupmembers: print user ObjId.manage_setLocalRoles(str(user),('Viewer',)) if str(allow) == 'community': print 'comm' ObjId.manage_permission(View, ('Manager','Owner','Viewer','Authenticated'), 0) return self.REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+str(id)) def manage_afterAdd(self, item, container): OrderedBaseFolder.manage_afterAdd(self, item, container) from zExceptions import BadRequest try: item._setObject('redirector', BlogRedirector()) except BadRequest: pass def displayContentsTab(self): return 0; def getBlogrollLinks(self): if not hasattr(self, 'blogrolllinks'): self.blogrolllinks = [] return self.blogrolllinks def setBlogrollLinks(self, REQUEST): if not hasattr(self, 'blogrolllinks'): self.blogrolllinks = [] blogrolllinks = self.getBlogrollLinks() add = True sameTitle = False sameLink = False new_link = REQUEST.get('new_link') new_title = REQUEST.get('new_title') for b in blogrolllinks: link = b[1] if link == new_link: sameLink = True title = b[0] print title if title == new_title: sameTitle = True if sameLink == False and sameTitle == False: self.blogrolllinks.append([REQUEST.get('new_title'), REQUEST.get('new_link')]) self.p_changed = 1 return [sameTitle, sameLink] def addLinkToBlogroll(self, REQUEST): self.blogrolllinks.append([REQUEST.get('new_title'), REQUEST.get('new_link')]) self.p_changed = 1 REQUEST.RESPONSE.redirect(self.absolute_url()) def delBlogrollLinks(self, REQUEST): if not hasattr(self, 'blogrolllinks'): self.blogrolllinks = [] c = 0 not_deleted_links = [] for link in self.blogrolllinks: if REQUEST.get('link_'+str(c))!='on': not_deleted_links.append(link) c = c + 1 self.blogrolllinks = not_deleted_links self.p_changed = 1 def getLargeIcon(self): """ returns large icon name """ return self.largeIcon def getBlogEntries(self, filter=False): res = [] tmp = [] pm = getToolByName(self,'portal_membership') be = self.objectValues(BLOG_TYPES) for x in be: if pm.checkPermission('View', x): # see if it is reflect or plan body = True if '-reflection-' in x.getId(): body = re.sub('<.*?>', '', x.getBody()).strip() if '-plan-' in x.getId(): body = re.sub('<.*?>', '', x.getBody()).strip() if not body: continue if not filter: tmp.append([x.CreationDate(), x]) else: try: if filter.has_key('category'): if filter['category'] in x.getCategories(): tmp.append([x.CreationDate(), x]) elif filter.has_key('tag'): if filter['tag'] in x.getTags(): tmp.append([x.CreationDate(), x]) except: pass tmp.sort() tmp.reverse() res = [ x[1] for x in tmp ] return res def getEveryoneBlogpostsByTag(self, show, user): """get everybodys blog posts""" tmp = [] pm = getToolByName(self,'portal_membership') pc = getToolByName(self, 'portal_catalog') ct = getToolByName(self, 'caching_tool') res = pc({'portal_type':BLOG_TYPES, 'getTags':show['show']},sort_on='modified', sort_order='descending') groups = self.getGroups() members = [] for group in groups: #groupmembers = group.getGroupMembers() groupmembers = ct._getGroupMembers(group) for mem in groupmembers: added = 1 for j in members: if mem.id == j: added = 0 if added == 1: members.append(mem.id) for y in res: if pm.checkPermission('View', y): x = y.getObject() has = 1 for z in members: if x.Creator() == z: has = 0 if x.Creator() == str(user): has = 0 if has == 1: tmp.append([x.CreationDate(), x]) tmp.sort() tmp.reverse() res = [ x[1] for x in tmp ] return res def getMyBlogpostsByTag(self, show, user): """get my blog posts""" tmp = [] pc = getToolByName(self, 'portal_catalog') res = pc({'portal_type':BLOG_TYPES, 'getTags':show['show'], 'Creator':str(user)},sort_on='modified', sort_order='descending') print res for y in res: x = y.getObject() tmp.append([x.CreationDate(), x]) tmp.sort() tmp.reverse() res = [ x[1] for x in tmp ] return res def getGroupBlogpostsByTag(self, show, user): """get everybodys blog posts""" tmp = [] pm = getToolByName(self,'portal_membership') pc = getToolByName(self, 'portal_catalog') ct = getToolByName(self, 'caching_tool') #res = pc({'portal_type':BLOG_TYPES, 'path':['OPAH','groupdata','']},sort_on='modified', sort_order='descending') res = pc({'portal_type':BLOG_TYPES, 'getTags':show['show']},sort_on='modified', sort_order='descending') groups = self.getGroups() members = [] for group in groups: #groupmembers = group.getGroupMembers() groupmembers = ct._getGroupMembers(group) for mem in groupmembers: added = 1 for j in members: if mem.id == j: added = 0 if added == 1: members.append(mem.id) for z in members: for y in res: if pm.checkPermission('View', y): x = y.getObject() if x.Creator() != str(user) and z == x.Creator(): tmp.append([x.CreationDate(), x]) tmp.sort() tmp.reverse() res = [ x[1] for x in tmp ] return res def getRecentBlogEntries(self): en = [] entries = self.getBlogEntries() showCount = 0 for x in entries: en.append(x) if showCount >= 4: break showCount = showCount + 1 return en def getDynamicCategories(self): dyn_cat = [] for dc in self.objectValues("BlogCategory"): dyn_cat.append(dc.Title()) return dyn_cat def getDynamicCategoryObjects(self): """return dynamic category obj list""" cats = self.objectValues("BlogCategory") cats.sort() return cats def removeDynamicCategories(self,REQUEST): """remove selected categories""" for_removing = REQUEST.get("cats_for_deleting") if for_removing: if isinstance(for_removing,str): for_removing = [for_removing] for fr in for_removing: if hasattr(self,fr): self._delObject(fr) return self.REQUEST.RESPONSE.redirect(self.absolute_url()+'/blog_preferences') def getNumberOfPostsByCategory(self,category): """returns number of posts""" numberOfPosts = 0 member_id = str(self.Creator()) portal_catalog = getToolByName(self, 'portal_catalog') results = portal_catalog.searchResults() for x in results: if x.Type in ['BlogEntry','ReflectionAnswer','StructuredAnswer'] and member_id in x.Creator: if x.getCategories: if category in x.getCategories: numberOfPosts = numberOfPosts + 1 return numberOfPosts def RSS(self, REQUEST): """ RSS feed """ REQUEST.RESPONSE.setHeader("Content-type", "text/xml; charset=utf-8") rss = """\n """ rss += "\t\n" rss += "\t%s\n" % self.Title() rss += "\t%s\n" % self.absolute_url() #rss += "\t%s\n" % self.Description() rss += "\tEportfolio\n" rss += "\ten\n" #rss += "\t\n" #rss += "\t\t%s\n" % self.getCoverImageURL() #rss += "\t\t%s\n" % self.absolute_url() #rss += "\t\n" tmp = [] pm = getToolByName(self,'portal_membership') #be = self.objectValues('BlogEntry') be = self.getBlogEntries() for x in be: if pm.checkPermission('View', x): tmp.append([x.CreationDate(), x]) tmp.sort() tmp.reverse() res = [ x[1] for x in tmp ] for x in res: if not hasattr(x.aq_base, 'getTags'): continue rss += "\t\n" rss += "\t\t%s\n" % x.Title() rss += "\t\t%s\n" % x.absolute_url() rss += "\t\t%s\n" % x.ModificationDate() rss += "\t\t%s\n" % x.Creator() rss += "\t\t%s\n" % ', '.join(x.getTags()) rss += "\t\t\n" % x.getBody() rss += "\t\n" rss += "\t\n" rss += "" return rss def makeTagCloud(self): """ generate a tagcloud """ taglist = self.getTagListSortedByFrequency() if taglist != []: # find max and min frequency ranges = self.getRanges(taglist) # write out results to output, tags are written out alphabetically # with size indicating the relative frequency of their occurence return self.writeCloud(taglist, ranges) return "" def getTagListSortedByFrequency(self): raw_tags = {} pc = getToolByName(self, 'portal_catalog') from Products.ZCatalog.ZCatalog import ZCatalog res = ZCatalog.searchResults(pc, {'portal_type':BLOG_TYPES,}) for r in res: if hasattr(r, 'getTags'): if not r.getTags: continue for rt in r.getTags: if rt!='': # otsing on liiga tundlik. #rt = re.sub('[.,\';!]', '', rt.strip()) #rt = rt.lower() #rt = rt.replace('Õ', 'õ') #rt = rt.replace('Ü', 'ü') #rt = rt.replace('Ä', 'ä') #rt = rt.replace('Ö', 'ö') if raw_tags.has_key(rt): raw_tags[rt] = raw_tags[rt] + 1 else: raw_tags[rt] = 1 taglist = [] for ts in raw_tags: taglist.append((ts, raw_tags[ts])) # sort tagdict by count taglist.sort(lambda x, y: cmp(x[1], y[1])) return taglist[-30:] def getRanges(self,taglist): mincount = taglist[0][1] maxcount = taglist[len(taglist) - 1][1] distrib = (maxcount - mincount) / 4; if (distrib == 0): distrib = 1 index = mincount ranges = [] while (index <= maxcount): #range = (index, index + distrib) index = index + distrib ranges.append(index) return ranges def writeCloud(self, taglist, ranges): html = "" rangeStyle = ["smallestTag", "smallTag", "mediumTag", "largeTag", "largestTag"] # resort the tags alphabetically taglist.sort(lambda x, y: cmp(x[0], y[0])) from bisect import bisect for tag in taglist: t = tag[0].strip() #+":"+ str(tag[1]) url = self.absolute_url()+"/blogs_view?show="+t style = "smallestTag" try: style = rangeStyle[bisect(ranges, tag[1])] except IndexError: pass html += "" + t + ", " return html registerType(BlogFolder, PROJECT_NAME) entry_schema = BaseSchema + Schema(( TextField('body', accessor='getBody', index='FieldIndex:schema', default_content_type = 'text/html', default_output_type = 'text/html', allowable_content_types = ('text/html',), widget=RichWidget( label='Body', label_msgid='label_blog_body', description='Write here what you have to say.', description_msgid='desc_blog_body', i18n_domain="eportfolio", rows=25, ), ), LinesField('categories', accessor='getCategories', searchable=1, index='KeywordIndex:schema', vocabulary='getCategoryVocab', enforceVocabulary=True, default='Post', widget=MultiSelectionWidget( label = 'Category', label_msgid='label_blog_categories', description = 'Select proper categories', description_msgid='desc_blog_categories', i18n_domain="eportfolio" ), ), TagsField('tags', accessor="getTags", searchable = 1, index = 'KeywordIndex:schema', widget=TagsWidget( label="Tags", label_msgid='label_tags', description="Enter some tags here separated by commas.", description_msgid='desc_tags', i18n_domain="eportfolio" ), ), ComputedField('trackbacklink', accessor='getTrackbacklink', index='FieldIndex:schema', widget=TrackbackLinkWidget( label='Trackback link', label_msgid='label_trackbacklink', description='Link for trackback. Copy it for trackbacking this post', description_msgid='desc_trackbacklink', i18n_domain="eportfolio" ), ), StringField('trackbackurl', accessor='getTrackbackurl', mutator='sendTrackback', widget=HelpWidget( label='Trackback url', label_msgid='label_trackbackurl', description='Copy trackback urls here, separated by ,', description_msgid='desc_trackbackurl', visible={'view':'invisible','edit':'visible'}, help_keyword='trackback', i18n_domain="eportfolio" ), ), ComputedField('rdffield', accessor='generateRDF', widget = ComputedWidget( label = 'hideme', use_label = False, visible = {'edit':'invisible', 'view': 'visible'}, ), ), DictField('trackbacks', accessor='getTrackbacks', mutator='setTrackback', hide_label = 1, widget=TrackbackWidget( label='Trackbacks were made from', label_msgid='label_trackbacks', description='Trackback', description_msgid='desc_trackbacks', visible={'view':'visible','edit':'invisible'}, i18n_domain="eportfolio" ), ), DictField('trackbacksmade', accessor='getTrackbacksmade', mutator='setTrackbacksmade', widget=TrackbacksMadeToWidget( label='Trackbacks were made to', label_msgid='label_trackbacksmade', use_label = False, description='Trackback', description_msgid='desc_trackbacksmade', visible={'view':'visible','edit':'invisible'}, i18n_domain="eportfolio" ), ), )) class BlogEntry(BaseContent): """ Blog entry """ meta_type = "BlogEntry" archetype_name = "BlogEntry" global_allow = 0 allowed_content_types = () security = ClassSecurityInfo() schema = entry_schema allow_discussion = True _at_rename_after_creation = True actions = ( { 'id':'view', 'name':'View', 'action':'string:${object_url}/base_view', 'permissions': ('View',), }, { 'id':'edit', 'name':'Edit', 'action':'string:${object_url}/base_edit', 'permissions': ('Modify portal content',), }, { 'id':'metadata', 'name':'Properties', 'action':'string:${object_url}/base_metadata', 'permissions': ('Manage Portal',), }, { 'id':'delete', 'name':'Delete', 'action':'string:${object_url}/delete_confirmation', 'permissions': ('Modify portal content',), }, { 'id':'competencies', 'name':'Associate with competency', 'action':'string:${object_url}/add_reference_to_competency?uid=${object/UID}', 'permissions': ('Modify portal content',), }, ) def manage_afterAdd(self, item, container): BaseContent.manage_afterAdd(self, item, container) from Products.CMFCore import permissions ManagePortal = permissions.ManagePortal self.manage_permission(ManagePortal, ('Manager','Owner',), 0) def __init__(self, id): self.id = id from DateTime import DateTime self.start = DateTime() self.end = self.start # def start(self): # """ """ # return self.getCreationDate() # def end(self): # """ """ # return self.getCreationDate() def getTrackbacklink(self): """this is trackbacklink""" return self.aq_parent.absolute_url()+"/redirector/trackback/"+str(self.UID()) def allowRestricted(self): return True def allowAccepted(self): return False def showEditableBorder(self, **args): return 0 def sendTrackback(self, value): if value: import urllib import urllib2 import urlparse import httplib link = self.getTrackbacklink() params = { 'url' : link, 'title' : self.Title(), 'blog_name' : self.Creator() + ' blog' } #param = '?url=' + link + '&title=' + urllib.quote(self.Title()) + '&blog_name=OPAH-Blog' urls = value.split(",") for url in urls: tmp = [] purl = urlparse.urlsplit(url) ext_pairs = purl[3].split('&') if len(ext_pairs)>1 and ext_pairs[0]: for x in ext_pairs: k, v = x.split('=') params[k] = v tmp.append(k) try: urlparams = urllib.urlencode(params) response = urllib2.urlopen(url, urlparams) #print "-------------- response for: ", url status = response.read().split("") if len(status) > 1: status = status[1].split("") status = status[0] else: status = 1 except ValueError: status = 1 self.setTrackbacksMadeTo(url,status) for x in tmp: del params[x] def _addTrackback(self, url, title='', excerpt='', blog_name=''): """add trackback to entry""" import time val = {'url':url,'title':title, 'excerpt':excerpt, 'blog_name':blog_name} f = self.getField('trackbacks').setValue(self, str(time.time()), val) def generateRDF(self): """ generate RDF """ return """ """ % (self.absolute_url(), self.Title(), self.getTrackbacklink()) def setTrackbacksMadeTo(self, url, status=''): """add trackback to entry""" import time trackback_id = "%.4f" %time.time() val = {'url':url,'status':status,} f = self.getField('trackbacksmade').setValue(self, trackback_id, val) security.declareProtected('Modify portal content', 'delTrackBackById') def delTrackBackById(self, REQUEST): """del object by id""" tb_id = REQUEST.get("id") for_delete = None trackbacks = self.getTrackbacks() for tb in trackbacks.keys(): if str(tb)==tb_id: for_delete = tb break f = self.getField('trackbacks').delValue(self, [for_delete]) return self.REQUEST.RESPONSE.redirect(self.absolute_url()) registerType(BlogEntry, PROJECT_NAME) category_schema = BaseSchema + Schema(( TextField('description', accessor='getDescription', widget=TextAreaWidget( label='Description', label_msgid='label_description', description='Add more information to your custom category', description_msgid='desc_description', i18n_domain="eportfolio", rows=5, ), ), )) class BlogCategory(BaseContent): """ Blog Category """ meta_type = "BlogCategory" archetype_name = "Blog Category" global_allow = 0 allowed_content_types = () security = ClassSecurityInfo() schema = category_schema #allow_discussion = True #_at_rename_after_creation = True actions = ( { 'id':'view', 'name':'View', 'action':'string:${object_url}/base_view', 'permissions': ('View',), }, { 'id':'edit', 'name':'Edit', 'action':'string:${object_url}/base_edit', 'permissions': ('Modify portal content',), }, { 'id':'metadata', 'visible':False, }, ) registerType(BlogCategory, PROJECT_NAME)