# -*- 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)