##############################################################################
#
# COREBlog.py
# Classes for COREBlog Site
#
# Copyright (c) 2003-2005 Atsushi Shibata. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided that
# the above copyright notice appear in all copies and that both that copyright
# notice and this permission notice appear in supporting documentation, and that
# the name of Atsushi Shibata not be used in advertising or publicity pertaining
# to distribution of the software without specific, written prior permission.
#
# ATSUSHI SHIBAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL SHIBAT ATSUSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
#
# This software uses stripogram,Copyright (c) 2001 Chris Withers
#
##############################################################################
#Import modules from Python lib.
from copy import copy
from string import join,split,find,replace
from time import time,mktime,localtime
from calendar import calendar,monthrange,setfirstweekday,weekday,monthcalendar
from calendar import SUNDAY,MONDAY,SATURDAY
from types import IntType,ListType
from poplib import POP3
from StringIO import StringIO
#from rotor import newrotor
from base64 import decodestring,encodestring
import os
#Import modules,classes from Zope.
#from zLOG import LOG,ERROR
from Globals import PersistentMapping,HTMLFile,MessageDialog,InitializeClass
from AccessControl import ClassSecurityInfo
from Acquisition import aq_base
from BTrees.IOBTree import IOBTree,IOSet
from BTrees.IIBTree import IISet
from App.Common import package_home
from DateTime import DateTime
from Products.ZCatalog import ZCatalog
from stripogram import html2safehtml,html2text
#Import modules,classes from COREBlog.
from Entry import Entry,excerpt_length,\
comment_none,comment_open,comment_closed,\
trackback_none,trackback_open,trackback_closed,\
format_html,format_plain,html_formats, \
get_rendered_body
from ObjectBase import Comment,Trackback
from Category import Category
from AuthBridge import AuthBridge
from utility import r2i,sec_to_date_int,day_to_date_int,get_yesterday,get_tomorrow, \
get_yesterday_t,get_tomorrow_t, \
remove_html,validate_html,getNewID,make_unique, \
call_addentry_hook, \
get_property_dict,required_object_list, \
get_skin_dicts,aplly_skin,addDTML,addGIF, \
convert_charcode, \
get_string_part,change_site_encode, \
add_skin_folder,add_files_to_folder, \
EmptyClass,split_in_newline, \
make_rotorkey, encrypt,decrypt,\
code_euc,code_sjis,code_utf8,code_jis,code_us, \
parse_blogger_post
from jmimetool import Message
from MailHolder import MailHolder
from permissions import View,ManageCOREBlog,AddCOREBlogEntries,\
AddCOREBlogComments,ModerateCOREBlogEntries
from Products.PythonScripts import PythonScript
__doc__="""Zope Blog Product 'COREBlog:COREBlog'
$Id: COREBlog.py,v 1.18 2006/04/03 14:07:28 ats_shib Exp $"""
__version__='$Revision: 1.18 $'[11:-2]
__product_version__ = "COREBlog 1.2.5"
manage_addCOREBlogForm=HTMLFile('dtml/manage_addCOREBlogForm',globals())
class COREBlog(ZCatalog.ZCatalog):
"""COREBlog - A Weblog Product for Zope"""
meta_type = 'COREBlog'
description = 'A Weblog Product for Zope'
#Interfaces
#Set default security settings
security = ClassSecurityInfo()
security.setPermissionDefault(ManageCOREBlog, ('Manager',))
security.setPermissionDefault(AddCOREBlogEntries,('Manager',))
security.setPermissionDefault(AddCOREBlogComments,('Anonymous','Manager',))
security.setPermissionDefault(ManageCOREBlog,('Manager',))
security.setPermissionDefault(View,('Anonymous','Manager',))
icon = 'misc_/COREBlog/coreblog_img'
#allowing tags
body_tags_id = "body_tags"
comment_tags_id = "comment_tags"
manage_options=( \
{'label':'Entries', 'icon':'', 'action':'manage_entryForm', 'target':'manage_main',
'help': ('COREBlog', 'Entries.stx') },
{'label':'Contents', 'icon':icon, 'action':'manage_main',
'target':'manage_main','help': ('COREBlog', 'Contents.stx') },
{'label':'View', 'icon':'', 'action':'index_html', 'target':'manage_main'},
{'label':'Settings', 'icon':'', 'action':'manage_editSettingForm', 'target':'manage_main',
'help': ('COREBlog', 'Settings.stx') },
#{'label':'Categories', 'icon':'', 'action':'manage_categoryForm', 'target':'manage_main',
# 'help': ('COREBlog', 'Categories.stx') },
#{'label':'Skins', 'icon':'', 'action':'manage_editSkinsettingForm', 'target':'manage_main'},
{'label':'Properties', 'icon':'', 'action':'manage_propertiesForm', 'target':'manage_main'},
{'label':'Security', 'icon':'', 'action':'manage_access', 'target':'manage_main'},
#{'label': 'Indexes', # TAB: Indexes
# 'action': 'manage_catalogIndexes',
# 'help': ('ZCatalog','ZCatalog_Indexes.stx')},
#{'label': 'Metadata', # TAB: Metadata
# 'action': 'manage_catalogSchema',
# 'help':('ZCatalog','ZCatalog_MetaData-Table.stx')},
#{'label': 'Find Objects', # TAB: Find Objects
# 'action': 'manage_catalogFind',
# 'help':('ZCatalog','ZCatalog_Find-Items-to-ZCatalog.stx')},
#{'label': 'Advanced', # TAB: Advanced
# 'action': 'manage_catalogAdvanced',
# 'help':('ZCatalog','ZCatalog_Advanced.stx')},
{'label':'Undo', 'icon':'', 'action':'manage_UndoForm', 'target':'manage_main'}
)
#Entry
security.declareProtected(ManageCOREBlog, 'manage_entryForm')
manage_entryForm = HTMLFile('dtml/manage_listEntryForm',globals())
security.declareProtected(ManageCOREBlog, 'manage_addEntryForm')
manage_addEntryForm = HTMLFile('dtml/manage_addEntryForm',globals())
security.declareProtected(ManageCOREBlog, 'manage_exportEntries')
manage_exportEntries = HTMLFile('dtml/manage_exportEntries',globals())
#Category
#security.declareProtected(ManageCOREBlog, 'manage_categoryForm')
#manage_categoryForm = HTMLFile('dtml/manage_listCategoryForm',globals())
security.declareProtected(ManageCOREBlog, 'manage_addCategoryForm')
manage_addCategoryForm = HTMLFile('dtml/manage_addCategoryForm',globals())
security.declareProtected(ManageCOREBlog, 'manage_editCategoryForm')
manage_editCategoryForm = HTMLFile('dtml/manage_editCategoryForm',globals())
#Settings
security.declareProtected(ManageCOREBlog, 'manage_editSettingForm')
manage_editSettingForm = HTMLFile('dtml/manage_editSettingForm',globals())
#security.declareProtected(ManageCOREBlog, 'manage_editSkinsettingForm')
#manage_editSkinsettingForm = HTMLFile('dtml/manage_editSkinsettingForm',globals())
#CSS
security.declareProtected(ManageCOREBlog, 'additional_css')
additional_css = HTMLFile('dtml/additional_css',globals())
security.declareProtected(View, 'cb_script_widget')
cb_script_widget = HTMLFile('dtml/coreblog_script_widget.js',globals())
#methods mapping for XML-RPC
#method name : [index of username,index of passwoed,remapped_method(optional)]
#mapping dictionaries
blogger_map = {
"newPost" :[2,3],
"editPost" :[2,3],
"deletePost" :[2,3],
"getRecentPosts" :[2,3],
"getUsersBlogs" :[1,2],
"getUserInfo" :[1,2],
}
metaweblog_map = {
"newPost" :[1,2,'newPostMW'],
"editPost" :[1,2,'editPostMW'],
"getPost" :[1,2],
"getRecentPosts" :[1,2,'getRecentPostsMW'],
#"newMediaObject" :[1,2],
}
mt_map = {
"getRecentPostTitles":[1,2],
"getCategoryList" :[1,2],
"getPostCategories" :[1,2],
"setPostCategories" :[1,2],
"editPost" :[1,2],
"getPost" :[1,2],
"supportedMethods" :[],
#"supportedTextFilters":[],
"getTrackbackPings" :[],
"publishPost" :[1,2],
}
#Blogger API
security.declareProtected(View, 'blogger')
blogger = AuthBridge("blogger")
blogger.set_proc_map(blogger_map)
#metaWeblog API
security.declareProtected(View, 'metaWeblog')
metaWeblog = AuthBridge("metaWeblog")
metaWeblog.set_proc_map(metaweblog_map)
#mt API
security.declareProtected(View, 'mt')
mt = AuthBridge("mt")
mt.set_proc_map(mt_map)
security.declarePrivate('__init__')
def __init__(self,id,title='COREBlog',encode="",elements=[]):
#Creater Function of COREBlog
self.id = id
#BTrees for sub objects & reference count
#Entries
self.entries = IOBTree()
self.entry_count = 1
self.entry_list = IISet()
#Comments
self.comments = IOBTree()
self.comment_count = 1
self.comment_list = IISet()
#Trackbacks
self.trackbacks = IOBTree()
self.trackback_count = 1
self.trackback_list = IISet()
#Entry list for date
self.datemap = IOBTree()
#Categories
self.categories = IOBTree()
self.category_count = 1
#folders
self.manage_addFolder('methods','Folder for Hook methods')
self.manage_addFolder('skin','Folder for Skin')
self.manage_addFolder('modules','Folder for Modules')
self.manage_addFolder('images','Folder for Images')
#rdf/rss
fullpath = os.path.join(package_home(globals()),"dtml/")
addDTML(os.path.join(fullpath,"rdf10_xml.dtml"),"rdf10_xml","RDF 1.0",self)
addDTML(os.path.join(fullpath,"rdf91_xml.dtml"),"rdf91_xml","RDF 0.91",self)
addDTML(os.path.join(fullpath,"rsd_xml.dtml"),"rsd_xml","RSD 1.0",self)
#bannar
imagepath = os.path.join(package_home(globals()),"www/")
addGIF(os.path.join(imagepath,"corebloglogo_gray.gif"),"corebloglogo","COREBlog",self.images)
#Add default skin
add_skin_folder(self.skin,"default","dtml/skin/default/",globals(),encode)
#Add plonified skin
add_skin_folder(self.skin,"plonified","dtml/skin/plonified/",globals(),encode)
add_skin_folder(self.skin.plonified,"portlets","dtml/skin/plonified/portlets/",globals(),encode)
#properties
self._properties = (get_property_dict())
#initialize properties
dics = get_property_dict()
for d in dics:
key = d["id"]
if d["type"] in ("string","text"):
self._updateProperty(key,"")
elif d["type"] in ("int","long"):
self._updateProperty(key,0)
elif d["type"] in ("boolean",):
self._updateProperty(key,0)
#set defaults
self._updateProperty("blog_url","")
self._updateProperty("module_item_count",10)
self._updateProperty("top_days",4)
self._updateProperty("category_length",20)
self._updateProperty("skin_name","default")
self._updateProperty("require_name",1)
self._updateProperty("use_epoz_service",0)
self._updateProperty("epoz_width",500)
self._updateProperty("epoz_height",250)
self._updateProperty("ping_servers","")
self._updateProperty("hide_entrydatetime",0)
self._updateProperty("hide_subtitle",0)
self._updateProperty("hide_subcategories",0)
self._updateProperty("hide_format",0)
self._updateProperty("hide_extend",0)
self._updateProperty("hide_excerpt",0)
self._updateProperty("hide_comment",0)
self._updateProperty("hide_trackback",0)
self._updateProperty("hide_status",0)
self._updateProperty("hide_trackbackurls",0)
self._updateProperty("textbox_width",80)
self._updateProperty("textarea_width",60)
self._updateProperty("body_height",20)
self._updateProperty("extend_height",6)
self._updateProperty("excerpt_height",6)
self.title = title
#add default modules
fullpath = os.path.join(package_home(globals()),"dtml/modules/")
add_files_to_folder(fullpath,self.modules,"")
#apply default skin
fullpath = os.path.join(package_home(globals()),"dtml/skin/default/")
add_files_to_folder(fullpath,self,"SKIN:default",encode)
#set property for default skin
skf = self.skin.default
prop_dict = [ {"id":"body_font", "type":"string","value":"verdana,georgia,arial,sans-serif"},
{"id":"background_color", "type":"string","value":"FFF"},
{"id":"font_color", "type":"string","value":"000"},
{"id":"banner_font", "type":"string","value":"arial,verdana,georgia, sans-serif"},
{"id":"banner_color", "type":"string","value":"FFF"},
{"id":"banner_font_color","type":"string","value":"000"},
{"id":"color1", "type":"string","value":"fff"},
{"id":"color2", "type":"string","value":"C0C0C0"},
{"id":"color3", "type":"string","value":"808080"},
{"id":"color4", "type":"string","value":"606060"},
{"id":"sidebox_background","type":"string","value":"FFF"}
]
for d in prop_dict:
skf.manage_addProperty(d["id"],d["value"],d["type"])
skf._updateProperty(d["id"],d["value"])
self.manage_addProperty(d["id"],d["value"],d["type"])
self._updateProperty(d["id"],d["value"])
#try to add lexicon...
try:
from Products.ZCTextIndex.ZCTextIndex import manage_addLexicon
if elements:
manage_addLexicon(self,id='lexicon',elements = elements)
except:
pass
#Build ZCatalog index
try:
self.buildIndex(self.id, self.title)
except:
pass
def blog(self):
""" return COREBlog instance """
return self
security.declareProtected(View, 'get_product_version')
def get_product_version(self):
return __product_version__ + "(Rev. %s)" % __version__
security.declareProtected(View, 'blog_title')
def blog_title(self):
""" return title of blog """
return self.title
security.declareProtected(View, 'blogurl')
def blogurl(self):
""" url of the COREBlog """
prop_url = self.getProperty("blog_url")
url = self.absolute_url()
if prop_url:
url = prop_url
return url
security.declarePublic('__len__')
def __len__(self):
return 1
security.declareProtected(View, '__getitem__')
def __getitem__(self,id):
""" return sub objects """
# Cast id to 'int'
try:
if not isinstance(id,IntType):
id=int(id)
except ValueError:
raise KeyError,id
if not self.entries.has_key(id):
raise KeyError,id
try:
obj = self.entries[id].__of__(self)
except:
pass
return self.entries[id].__of__(self)
#
# Methods for Entry Handling
#
security.declareProtected(AddCOREBlogEntries, 'manage_addEntry')
def manage_addEntry(self,author,body,extend="",excerpt="", \
main_category=0,moderated=0,sub_category=[], \
title="",subtitle="", entry_date="", \
format=0,allow_comment=0,receive_trackback=0,
trackback_url="",sendnow=0,REQUEST=None,
sendping = 1,**kw):
"""Add a Entry object"""
#validaters
v_h = self.removeHTML
v_b = self.validateEntryBody
v_c = self.validateCommentBody
if REQUEST and (REQUEST.form.has_key('preview') or not title):
if not entry_date:
entry_date = str(DateTime())
cats = []
try:
cats.append(self.getCategory(main_category)[0])
for ct in sub_category:
cats.append(self.getCategory(int(ct))[0])
except:
pass
message = ''
if not title:
message = 'Title is required.'
if main_category in [0,-1]:
message = 'Please select main category.'
kw['date_created'] = lambda x=entry_date : DateTime(x)
kw['year_created'] = lambda x=entry_date: DateTime(x).year()
kw['day_created'] = lambda x=entry_date: DateTime(x).day()
kw['month_created'] = lambda x=entry_date: DateTime(x).month()
kw['entry_category_list'] = lambda x=cats: x
kw['tbpingurl'] = lambda : "not defined on pewview"
kw['entry_title'] = lambda x=v_h(title) : x
kw['title'] = v_h(title)
kw['subtitle'] = v_h(subtitle)
kw['count_comment'] = lambda : 0
kw['count_trackback'] = lambda : 0
kw['format'] = format
if format in html_formats:
kw['rendered_body'] = v_b(body)
kw['body'] = v_b(body)
kw['extend'] = v_b(extend)
else:
kw['rendared_body'] = body
kw['body'] = body
kw['extend'] = extend
#Set control values
kw['noheader'] = 1
kw['nocomment'] = 1
kw['nocommentform'] = 1
#Returns addEntryForm
return self.manage_addEntryForm(self,REQUEST,manage_tabs_message=message,**kw)
new_id = self.getNewEntryID()
#remove category duplications
cats_s = [main_category] + sub_category
cats = []
for id in cats_s:
if not self.categories.has_key(int(id)):
raise ValueError,"Category of ID(%s) does not exist." % (str(id))
cats.append(int(id))
cats = make_unique(cats)
if not excerpt:
prebody = html2text(v_h(get_rendered_body(body,format)))
excerpt = get_string_part(prebody,excerpt_length,self.get_charcode())
if len(excerpt) < len(prebody):
excerpt = excerpt + "..."
tburls = split_in_newline(trackback_url)
crsec = time()
if entry_date:
crsec = int(DateTime(entry_date).millis()/1000)
cooked_body = body
cooked_excerpt = excerpt
if format in html_formats:
cooked_body = v_b(body)
cooked_excerpt = v_b(excerpt)
obj = Entry(new_id, \
v_h(author),cooked_body,v_b(extend),v_c(excerpt), \
moderated,title,subtitle,cats, \
format,allow_comment,receive_trackback, \
tburls,crsec)
obj.__of__(self)
self.setEntry(new_id,obj)
self.entry_list.insert(new_id)
#add category count
if moderated:
self.addCategoryCount(cats[0],1)
self._p_changed = 1
#Catalogging...
obj.index(self)
call_addentry_hook(self,new_id,v_h(author),cooked_body,v_b(extend),v_c(excerpt), \
moderated,title,subtitle,cats, \
format,allow_comment,receive_trackback)
pingservers_prop = self.getProperty("ping_servers")
pingservers = []
if pingservers_prop:
for srv in pingservers_prop:
if srv:
pingservers.append(srv)
if moderated:
if REQUEST:
if sendnow and obj.count_sending_trackback() > 0 and obj.date_created() <= DateTime():
return REQUEST.RESPONSE.redirect('./' + str(new_id) + "/manage_sendPINGTrackback")
elif pingservers and len(pingservers) > 0 and obj.date_created() <= DateTime():
return REQUEST.RESPONSE.redirect('./' + str(new_id) + "/manage_sendPINGTrackback")
else:
return REQUEST.RESPONSE.redirect('manage_entryForm')
elif sendping and obj.date_created() <= DateTime():
#Entry might add via mail....
obj.aq_parent = self
obj.sendPING()
else:
if REQUEST:
return REQUEST.RESPONSE.redirect('manage_entryForm')
return new_id
security.declareProtected(ManageCOREBlog, 'manage_deleteEntries')
def manage_deleteEntries(self,ids,REQUEST=None):
"""Delete Entries in list(ids)"""
if type(ids) != ListType:
raise TypeError,"Paramater 'ids' must be a ListType."
for id in ids:
int_id = int(id)
if not self.entries.has_key(int_id):
raise ValueError,"A entry(ID:%s) does not exist." % (str(int_id))
self.deleteEntry(int_id)
if REQUEST:
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
security.declarePrivate('setEntry')
def setEntry(self,id,obj):
#Append a Entry object to self.entries
self.entries[id] = obj
#Append Entry to date_map,considering moderation
self.setDatemap(obj)
self._p_changed = 1
security.declarePrivate('deleteEntry')
def deleteEntry(self,id):
int_id = int(id)
#delete entry
obj = self.getEntry(int_id)
#remove from entry_list
self.entry_list.remove(int_id)
#remove from date_map
self.removeIDFromDatemap(obj.year_created(), \
obj.month_created(),obj.day_created(),int_id)
#delete comments of entry
obj.deleteAllComments()
#delete trackback of entry
obj.deleteAllTrackbacks()
#decrement category count
if obj.category:
self.addCategoryCount(obj.category[0],-1)
#delete from IOBtree entries
del self.entries[int_id]
self._p_changed = 1
security.declarePrivate('getEntry')
def getEntry(self,id):
#Return a Entry object
int_id = int(id)
if not self.entries.has_key(int_id):
return None
else:
obj = self.entries[int_id].__of__(self)
return obj
security.declareProtected(View, 'get_entry')
def get_entry(self,id):
"""puglic interface for getting entry object from id"""
return self.getEntry(id)
#Indexing
security.declarePrivate('buildIndex')
def buildIndex(self,id,title):
if not hasattr(self,'_catalog'):
ZCatalog.ZCatalog.__init__(self,id,title)
for name in self.indexes():
self.delIndex(name)
index_dict = [ {"key":"author","type":"FieldIndex"},
{"key":"search_text","type":"ZCTextIndex"},
{"key":"title","type":"ZCTextIndex"},
{"key":"created","type":"FieldIndex"}
]
for d in index_dict:
if d["type"] != "ZCTextIndex":
self.addIndex(d["key"],d["type"])
else:
extras = EmptyClass()
extras.doc_attr = d["key"]
extras.index_type = 'Okapi BM25 Rank'
extras.lexicon_id = 'lexicon'
self.addIndex(d["key"],d["type"],extra=extras)
for name in self.schema():
self.delColumn(name)
catalog_columns = ['id','title','author','created']
for name in catalog_columns:
self.addColumn(name,'')
security.declareProtected(ManageCOREBlog, 'recatalogEntries')
def recatalogEntries(self,REQUEST=None):
""" Recatalog all Entries """
self.buildIndex(self.id, self.title)
self._catalog.clear()
for obj in self.entry_items():
obj.index(self)
if REQUEST is not None:
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
#Listing
security.declareProtected(View, 'entry_items')
def entry_items(self,start=0,count=-1,consider_moderation = 1):
"""Return list of Entry."""
start = r2i(start,0)
count = r2i(count,-1)
consider_moderation = r2i(consider_moderation,1)
l = []
list_c = len(self.entry_list)
if count == -1:
count = list_c
for c in range(start,count):
if list_c <= c:
#index out of range
break
id = self.entry_list[c]
obj = self.getEntry(id)
if not consider_moderation or obj.moderated:
l.append(obj)
return l
security.declareProtected(View, 'rev_entry_items')
def rev_entry_items(self,start=0,count=-1,consider_moderation = 1):
"""Return list of Entry(reversed indexing)."""
start = r2i(start,0)
count = r2i(count,-1)
consider_moderation = r2i(consider_moderation,1)
l = []
if count == -1:
count = len(self.entry_list)
l_e = len(self.entry_list) - 1
for c in range(start,start+count):
if l_e < c:
#index out of range
break
id = self.entry_list[l_e - c]
obj = self.getEntry(id)
if (not consider_moderation) or (obj.moderated and obj.date_created() < DateTime()):
l.append(obj)
return l
security.declareProtected(View, 'day_entry_items')
def day_entry_items(self,year,month,day):
"""Return entries of the day"""
try:
int_year = int(year)
int_month = int(month)
int_day = int(day)
except:
return []
d_set = self.getExistingDateSet(int_year,int_month,int_day)
if not d_set:
return []
ent_list = []
for entry_id in d_set:
obj = self.getEntry(entry_id)
obj.__of__(self)
if obj.date_created() < DateTime():
ent_list.append(obj)
return ent_list
security.declareProtected(View, 'rev_day_entry_items')
def rev_day_entry_items(self,count=1,start_year=0,start_month=0,start_day=0):
"""Return list of Entry,based on date(reversed indexing)."""
count = r2i(count,0)
start_year = r2i(start_year,0)
start_month = r2i(start_month,0)
start_day = r2i(start_day,0)
if start_year == 0 or start_month == 0 or start_day == 0:
#Base date is today
t = localtime(time())
year = t[0]
month = t[1]
day = t[2]
else:
year = start_year
month = start_month
day = start_day
ent_l = []
if not self.datemap:
#No entry...
return ent_l
c = 0
day_l = []
year_list = list(self.datemap.keys())
year_list.sort()
year_list.reverse()
#start from 'year'
if year != year_list[0]:
cyear_list = copy(year_list)
for key in cyear_list:
if key > year:
year_list.remove(key)
for y_key in year_list:
month_set = self.datemap[y_key]
month_list = list(self.datemap[y_key].keys())
month_list.sort()
month_list.reverse()
if year == y_key and month_list:
#start from 'month'
cmonth_list = copy(month_list)
for m_key in cmonth_list:
if m_key > month:
month_list.remove(m_key)
for m_key in month_list:
day_set = month_set[m_key]
day_list = list(month_set[m_key].keys())
day_list.sort()
day_list.reverse()
if year == y_key and month == m_key and day_list:
#start from 'day'
cday_list = copy(day_list)
for d_key in cday_list:
if d_key > day:
day_list.remove(d_key)
for d_key in day_list:
day_l = list(day_set[d_key])
day_l.reverse()
for id in day_l:
obj = self.getEntry(id)
obj.__of__(self)
if obj.date_created() <= DateTime():
ent_l.append(obj)
c = c + 1
if c >= count:
break
if c >= count:
break
if c >= count:
break
return ent_l
security.declareProtected(View, 'month_entry_items')
def month_entry_items(self,count=1,year=0,month=0):
"""Return list of Entry on the month."""
count = r2i(count,1)
year = r2i(year,0)
month = r2i(month,0)
if year == 0 or month == 0:
#Base date is today
t = localtime(time())
show_year = t[0]
show_month = t[1]
else:
show_year = int(year)
show_month = int(month)
show_day = 1
ent_l = []
if not self.datemap:
#No entry...
return ent_l
if not self.getExistingDateSet(show_year,show_month,show_day):
#There is no entry on the date.
#So we are going to find date has some entry.
while not self.getExistingDateSet(show_year,show_month,show_day) and \
year == show_year and month == show_month:
show_year,show_month,show_day = get_tomorrow_t(show_year,show_month,show_day)
if show_year != year or show_month != month:
return []
c_year = show_year
c_month = show_month
while c_year == show_year and c_month == show_month:
day_l = list(self.getExistingDateSet(show_year,show_month,show_day))
for id in day_l:
obj = self.getEntry(id)
if obj.date_created() < DateTime():
ent_l.append(obj)
c_year = show_year
c_month = show_month
#get 'tomorrow'
show_year,show_month,show_day = get_tomorrow_t(show_year,show_month,show_day)
while not self.getExistingDateSet(show_year,show_month,show_day) and \
c_year == show_year and c_month == show_month:
show_year,show_month,show_day = get_tomorrow_t(show_year,show_month,show_day)
return ent_l
security.declareProtected(View, 'month_archive_items')
def month_archive_items(self,count=1,start_year=0,start_month=0):
""" Return list of month archive. """
count = r2i(count,1)
start_year = r2i(start_year,0)
start_month = r2i(start_month,0)
if start_year == 0 or start_month == 0 or start_day == 0:
#Base date is today
t = localtime(time())
year = t[0]
month = t[1]
else:
year = year
month = month
ret_l = []
cnt = 100 #limitter
while cnt > 0 and count > 0:
if not self.datemap.has_key(year):
cnt = cnt - 1
month = 12
year = year - 1
continue
year_s = self.datemap[year]
if year_s.has_key(month):
ret_l.append({"year":year,"month":month})
count = count - 1
month = month - 1
if month < 1:
month = 12
year = year - 1
cnt = cnt - 1
return ret_l
security.declareProtected(View, 'getMonthName')
def getMonthName(self,month):
""" Return month name. """
m_list = ["January","February","March","April", \
"May","June","July","August", \
"September","October","November","December"]
if self.hasProperty("month_names"):
tmp_mlist = split(self.getProperty("month_names"),",")
if len(tmp_mlist) == 12:
m_list = tmp_mlist
month = int(month)
if month < 1 or month > 12:
return ""
return m_list[month-1]
def get_entry_in_category(self,category_id,consider_moderation = 1):
#Returns entries in category
l = []
for id in self.entry_list:
obj = self.getEntry(id)
if obj.category and obj.category[0] == category_id:
if not consider_moderation or (obj.moderated and obj.date_created() <= DateTime()):
l.append(obj)
return l
security.declareProtected(View, 'rev_category_entry_items')
def rev_category_entry_items(self,category_id,start=0,count=-1,consider_moderation = 1):
"""Return list of Entry(chronological order)."""
category_id = r2i(category_id)
start = r2i(start,0)
count = r2i(count,1)
consider_moderation = r2i(consider_moderation,1)
l = []
try:
int_cat = int(category_id)
except:
return []
list_c = len(self.entry_list)
if count == -1:
count = list_c
return self.get_entry_in_category(int_cat,consider_moderation)[start:start+count]
security.declareProtected(View, 'category_entry_items')
def category_entry_items(self,category_id,start=0,count=-1,consider_moderation = 1):
"""Return list of Entry."""
try:
int_cat = int(category_id)
except:
return []
l = self.get_entry_in_category(int_cat,consider_moderation)
l.reverse()
return l[start:start+count]
security.declareProtected(View, 'count_entry')
def count_entry(self):
"""Return count of Entry."""
return len(self.entries)
security.declarePrivate('getNewEntryID')
def getNewEntryID(self):
#return new id for entry
new_id = getNewID(self.entry_count,self.entries)
self.entry_count = new_id
return new_id
#
# datemap Handling
#
security.declarePrivate('getDateSet')
def getDateSet(self,year,month,day):
if self.datemap.has_key(year):
y_set = self.datemap[year]
else:
y_set = IOBTree()
self.datemap[year] = y_set
if y_set.has_key(month):
m_set = y_set[month]
else:
m_set = IOBTree()
y_set[month] = m_set
if m_set.has_key(day):
d_set = m_set[day]
else:
d_set = IOSet()
m_set[day] = d_set
return d_set
security.declarePrivate('getExistingDateSet')
def getExistingDateSet(self,year,month,day):
if self.datemap.has_key(year):
y_set = self.datemap[year]
else:
return None
if y_set.has_key(month):
m_set = y_set[month]
else:
return None
if m_set.has_key(day):
d_set = m_set[day]
else:
return None
return d_set
security.declarePrivate('getExistingMonthSet')
def getExistingMonthSet(self,year,month):
if self.datemap.has_key(year):
y_set = self.datemap[year]
else:
return None
if y_set.has_key(month):
m_set = y_set[month]
else:
return None
return m_set
security.declarePrivate('getExistingMonthSet')
def getExistingMonthSet(self,year,month):
if self.datemap.has_key(year):
y_set = self.datemap[year]
else:
return None
if y_set.has_key(month):
m_set = y_set[month]
else:
return None
return d_set
security.declarePrivate('setIDToDatemap')
def setIDToDatemap(self,year,month,day,id):
d_set = self.getDateSet(year,month,day)
int_id = int(id)
d_set.insert(int_id)
security.declarePrivate('removeIDFromDatemap')
def removeIDFromDatemap(self,year,month,day,id):
d_set = self.getDateSet(year,month,day)
int_id = int(id)
if d_set.has_key(int_id):
d_set.remove(int_id)
#remove year,date
if self.datemap.has_key(year):
y_set = self.datemap[year]
if y_set.has_key(month):
m_set = y_set[month]
if not m_set[day]:
del m_set[day]
if not y_set[month]:
del y_set[month]
security.declarePrivate('setDatemap')
def setDatemap(self,obj):
#Consider moderation...
if obj.moderated:
self.setIDToDatemap(obj.year_created(),obj.month_created(),obj.day_created(),int(obj.id))
else:
self.removeIDFromDatemap(obj.year_created(),obj.month_created(),obj.day_created(),int(obj.id))
#
# Methods for Comment Handling
#
security.declarePrivate('setComment')
def setComment(self,id,obj):
#Append a Comment object to self.comments
if not self.comments.has_key(id):
self.comment_list.insert(id)
self.comments[id] = obj
security.declarePrivate('deleteComment')
def deleteComment(self,id):
#Delete a Comment object from self.comments
if self.comments.has_key(id):
del self.comments[id]
self.comment_list.remove(id)
self._p_changed = 1
security.declarePrivate('getComment')
def getComment(self,id):
if not self.comments.has_key(id):
raise KeyError,id
return self.comments[id]
#security.declarePrivate('getNewCommentID')
def getNewCommentID(self):
#return new id for comments
new_id = getNewID(self.comment_count,self.comments)
self.comment_count = new_id
return new_id
security.declareProtected(View, 'rev_comment_items')
def rev_comment_items(self,start=0,count=-1):
"""Return list of Comment(reversed indexing)."""
start = r2i(start,0)
count = r2i(count,-1)
l = []
if count == -1:
count = len(self.comment_list)
l_e = len(self.comment_list) - 1
while count > 0:
if l_e < 0:
#index out of range
break
id = self.comment_list[l_e]
obj = self.getComment(id)
l_e = l_e - 1
if obj.moderated:
l.append(obj)
count = count - 1
return l
security.declareProtected(View, 'count_blog_comment')
def count_blog_comment(self):
"""return count of Comment."""
return len(self.comment_list)
#
# Methods for Trackback Handling
#
security.declarePrivate('setTrackback')
def setTrackback(self,id,obj):
#Append a Comment object to self.entries
if not self.trackbacks.has_key(id):
self.trackback_list.insert(id)
self.trackbacks[id] = obj
security.declarePrivate('deleteTrackback')
def deleteTrackback(self,id):
#Delete a Trackback object from self.trackbacks
if self.trackbacks.has_key(id):
del self.trackbacks[id]
self.trackback_list.remove(id)
self._p_changed = 1
security.declarePrivate('getTrackback')
def getTrackback(self,id):
if not self.trackbacks.has_key(id):
raise KeyError,id
return self.trackbacks[id]
def getNewTrackbackID(self):
#return new id for trackback
new_id = getNewID(self.trackback_count,self.trackbacks)
self.trackback_count = new_id
return new_id
security.declareProtected(View, 'rev_trackback_items')
def rev_trackback_items(self,start=0,count=-1):
"""Return list of Trackback(reversed indexing)."""
start = r2i(start,0)
count = r2i(count,-1)
l = []
if count == -1:
count = len(self.trackback_list)
l_e = len(self.trackback_list) - 1
while count > 0:
if l_e < 0:
#index out of range
break
id = self.trackback_list[l_e]
obj = self.getTrackback(id)
l_e = l_e - 1
if obj.moderated:
l.append(obj)
count = count - 1
return l
security.declareProtected(View, 'count_blog_trackback')
def count_blog_trackback(self):
"""Return count of Trackback."""
return len(self.trackback_list)
#
# Methods for calendar handling
#
security.declareProtected(View, 'get_calendar')
def get_calendar(self,year=0,month=0,firstweekday=SUNDAY):
"""Reutrn list of days for the month"""
if year == 0 or month == 0:
#return calendar of 'now'
t = localtime(time())
year = t[0]
month = t[1]
else:
year = int(year)
month = int(month)
setfirstweekday(firstweekday)
days = monthcalendar(year,month)
week_list = []
for week in days:
d_l = []
for day in week:
d_l.append({"day":day,"entry_count":self.countEntryOfTheDay(year,month,day)})
week_list.append(d_l)
return week_list
security.declareProtected(View, 'countEntryOfTheDay')
def countEntryOfTheDay(self,year,month,day):
"""Return count of entry of the day"""
d_set = self.getExistingDateSet(year,month,day)
if d_set:
ent_l = []
for id in d_set:
obj = self.getEntry(id)
if obj.date_created() <= DateTime():
ent_l.append(id)
return len(ent_l)
else:
return 0
#
# Methods for Category Handling
#
security.declareProtected(ManageCOREBlog, 'addCategory')
def addCategory(self,name,description,icon_path="",sec = -1):
"""Add a Category"""
new_id = self.getNewCategoryID()
obj = Category(new_id,name,description,icon_path,sec)
obj.__of__(self)
self.setCategory(new_id,obj)
return new_id
security.declareProtected(ManageCOREBlog, 'manage_addCategory')
def manage_addCategory(self,name,description,icon_path="",REQUEST=None):
"""Add a Category"""
self.addCategory(name,description,icon_path)
#call_script(self,"",{})
if REQUEST:
return REQUEST.RESPONSE.redirect(\
'manage_editSettingForm?section:int=1')
security.declareProtected(ManageCOREBlog, 'manage_deleteCategories')
def manage_deleteCategories(self,ids,REQUEST=None):
"""Delete Category in list(ids)"""
if type(ids) != ListType:
raise TypeError,"Paramater 'ids' must be a ListType."
for id in ids:
id_s = int(id)
if not self.categories.has_key(id_s):
raise ValueError,"A category(ID:%s) does not exist." % (str(id_s))
obj = self.categories[id_s]
del self.categories[id_s]
del obj
if REQUEST:
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
security.declarePrivate('setCategory')
def setCategory(self,id,obj):
#Append a Category object to self.entries
self.categories[id] = obj
security.declarePrivate('addCategoryCount')
def addCategoryCount(self,cat_id,delta):
#add category count
cat = self.categories[cat_id]
cat.set_count(cat.get_count()+delta)
security.declareProtected(View, 'getCategory')
def getCategory(self,id):
""" Reruth specific category. """
id_i = r2i(id)
if not self.categories.has_key(id_i):
raise KeyError,id_i
return (self.categories[id_i],)
security.declarePrivate('getNewCategoryID')
def getNewCategoryID(self):
#return new id for category
new_id = getNewID(self.category_count,self.categories)
self.category_count = new_id
return new_id
security.declareProtected(ManageCOREBlog, 'count_category')
def count_category(self):
return len(self.categories)
security.declareProtected(View, 'category_list')
def category_list(self):
""" return all category list. """
cats = []
for id in self.categories.keys():
obj = self.categories[id]
#obj.__of__(self)
cats.append(obj)
return cats
security.declareProtected(ManageCOREBlog, 'manage_editCategory')
def manage_editCategory(self,id,name,description,icon_path,REQUEST=None):
"""edit category"""
obj = self.getCategory(id)
obj[0].edit(name,description,icon_path)
if REQUEST:
return REQUEST.RESPONSE.redirect(\
'manage_editSettingForm?section:int=1')
security.declareProtected(ManageCOREBlog, 'manage_calculateCategory')
def manage_calculateCategory(self,REQUEST=None):
"""recalculate category counts"""
for key in self.categories.keys():
cat = self.categories[key]
cat.set_count(0)
for id in self.entry_list:
ent = self.getEntry(id)
if ent.category and self.categories.has_key(ent.category[0]):
cat = self.categories[ent.category[0]]
cat.set_count(cat.get_count()+1)
#reset datemap
self.datemap = IOBTree()
objs = self.entry_items()
for obj in objs:
self.setIDToDatemap(obj.year_created(),obj.month_created(),obj.day_created(),obj.id)
if REQUEST:
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
#
# Methods for settings
#
security.declareProtected(ManageCOREBlog, 'manage_editSettings')
def manage_editSettings(self,REQUEST=None):
"""set the setting values"""
if REQUEST:
pre_charcode = ""
if self.hasProperty("management_page_charset"):
pre_charcode = self.getProperty("management_page_charset")
dics = get_property_dict()
for d in dics:
key = d["id"]
if key in ["moblog_password","entry_password"] and \
REQUEST.form.has_key(key):
if not hasattr(self,'_rotorkey'):
self._rotorkey = make_rotorkey()
if not REQUEST.form[key] == "password":
#value changed.
setattr(self,'_' + key,encodestring(encrypt(REQUEST.form[key],self._rotorkey)))
REQUEST.form[key] = ""
if REQUEST.form.has_key(key):
if self.hasProperty(key):
self._updateProperty(key,REQUEST.form[key])
else:
self.manage_addProperty(key,REQUEST.form[key],d["type"])
cbd = {0:[],
1:[],
2:['use_epoz_service','hide_subtitle','hide_entrydatetime','hide_extend',
'hide_subcategory','hide_excerpt','hide_comment','hide_trackbackurls'],
3:['require_name','require_email','moderate_comment','moderate_trackback','moderate_noreference_trackback','check_session_on_comment'],
4:[],
5:['useapop','allow_comment_moblog','allow_trackback_moblog']}
if REQUEST.form.has_key('section') and cbd.has_key(REQUEST.form['section']):
for key in cbd[REQUEST.form['section']]:
if self.hasProperty(key) and not REQUEST.form.has_key(key):
self._updateProperty(key,0)
#Change objects charset if need...
if self.hasProperty("management_page_charset"):
post_charcode = self.getProperty("management_page_charset")
if REQUEST.has_key("change_charcode") and pre_charcode != post_charcode:
change_site_encode(self,post_charcode,pre_charcode)
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
#
# Methods for skin settings
#
security.declareProtected(ManageCOREBlog, 'manage_editSkinsettings')
def manage_editSkinsettings(self,REQUEST=None):
"""set the skin setting values"""
if REQUEST:
l = get_skin_dicts(self)
if l[self.getProperty("skin_name")].has_key("skin_properties"):
dics = l[self.getProperty("skin_name")]["skin_properties"]
for d in dics:
key = d["id"]
if REQUEST.form.has_key(key):
if self.hasProperty(key):
self._updateProperty(key,REQUEST.form[key])
else:
self.manage_addProperty(key,REQUEST.form[key],d["type"])
elif d["type"] == "boolean" and self.hasProperty(key):
self._updateProperty(key,0)
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
security.declareProtected(ManageCOREBlog, 'manage_changeSkin')
def manage_changeSkin(self,after,before,REQUEST=None):
"""change the skin"""
aplly_skin(self,after,before)
self._updateProperty("skin_name",after)
if REQUEST:
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
security.declareProtected(ManageCOREBlog, 'skin_items')
def skin_items(self):
"""return list of skin"""
l = get_skin_dicts(self)
ol = []
for key in l.keys():
ol.append(l[key]["skin_folder"])
return ol
security.declareProtected(ManageCOREBlog, 'manage_importSkins')
def manage_importSkins(self,REQUEST=None):
"""import thridparty skins"""
import dircache
basepath = os.path.join(package_home(globals()),
os.path.join('www','skins'))
for f in dircache.listdir(basepath):
if f.find('zexp') != 0:
try:
self.skin._importObjectFromFile(os.path.join(basepath,f))
except:
pass
if REQUEST:
return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
#
# Moblog
#
security.declareProtected(AddCOREBlogEntries,'receive')
def receive(self):
"""Receive mails"""
#create a POP3 client instance
m = POP3(self.getProperty("mailhost"))
#Authenticate
passwd = decrypt(decodestring(self._moblog_password),self._rotorkey)
if self.getProperty("useapop"):
m.apop(self.getProperty("moblog_user"),passwd)
else:
m.user(self.getProperty("moblog_user"))
m.pass_(passwd)
#get number of total message.
total = len(m.list()[1])
#get uid list
l = m.uidl()[1]
#make valid uid list
suidls = []
for uidline in l:
ut = split(uidline," ")
if len(ut) > 0:
suidls.append(ut[len(ut)-1])
else:
suidls.append(uidline)
if not hasattr(self,"uidls"):
self.uidls = []
self._p_changed = 1
cnt = 1
uidl_changed = 0
for uid in suidls:
if uid not in self.uidls:
#New mail arrived...
ml = m.retr(cnt)[1]
buf = StringIO(join(ml,"\n"))
mail = Message(buf,self.getProperty("management_page_charset"))
self.add_mail_entry(mail)
uidl_changed = 1
cnt = cnt + 1
if uidl_changed:
self.uidls = suidls
self._p_changed = 1
m.quit()
security.declarePrivate('add_mail_entry')
def add_mail_entry(self,mail):
#add entry from mail
#If image was attached,
ret = ""
mh = MailHolder(mail)
maild = mail.get_parts()
bd = ""
pd = []
mainpart = 0
bdbuf = None
for d in maild:
if mainpart == 0 and find(d["type"],"text") != -1:
#main part found
mainpart = 1
bdbuf = d["data"]
else:
pd.append(d)
if not bdbuf:
return
#check sender
sender_list = mh.getSenderList()
allowed_email = self.getProperty("moblog_email_addr")
if allowed_email:
#check sender.
go = 0
ae_list = split(allowed_email,",")
for addr in ae_list:
for sndr in sender_list:
if find(sndr,addr) != -1:
go = 1
break;
if go:
break
if not go:
#sender was mismatched....
return
#check password
bdbuf.seek(0)
pwline = replace(bdbuf.readline(),"\n","")
passwd = decrypt(decodestring(self._entry_password),self._rotorkey)
if pwline == passwd:
#password matched
body_l = []
separater = self.getProperty("body_separater")
cnt = 0
lines = bdbuf.readlines()
for line in lines:
line = replace(line,"\n","")
line = replace(line,"\r","")
if line and ord(line[0]) == 32:
#remove first space
line = line[1:]
if len(separater) > 0 and line == separater:
break
body_l.append(line)
cnt = cnt + 1
#add entry...
#find a category
in_cats = split(body_l[0]," ")
adding_cats = []
cats = self.category_list()
for cat in in_cats:
for scat in cats:
if scat.name == cat or scat.id == cat:
adding_cats.append(int(scat.id))
img_folder = self.images
pict_attached = 0
pictid = ""
if len(pd) > 0:
#try adding a image
serial = self.getProperty("image_serial") + 1
pictid = "img_" + str(serial)
img_folder.manage_addImage(pictid,\
pd[0]["data"],"","",pd[0]["type"])
self._updateProperty("image_serial",serial)
pict_attached = 1
#add entry body
if len(body_l) > 1:
blog_charcode = self.getProperty("management_page_charset")
posting_title = mh.getSubject()
posting_body = join(body_l[1:],"\n")
if pict_attached:
posting_body = """\n""" % (pictid) + posting_body
main_category = self.getProperty("moblog_default_category")
sub_category = []
if adding_cats:
main_category = adding_cats[0]
if len(adding_cats) > 1:
sub_category = adding_cats[1:]
comment_status = comment_open
trackback_status = trackback_open
if not self.getProperty("allow_comment_moblog"):
comment_status = comment_none
if not self.getProperty("allow_trackback_moblog"):
trackback_status = trackback_none
new_id = self.manage_addEntry(self.getProperty("author_for_moblog"),\
posting_body,"","",\
main_category,1,sub_category,\
posting_title,"","",0,comment_status,trackback_status)
if pict_attached:
try:
#set metadata(title,permalink) to added image
img_folder = self.images
img_obj = img_folder[pictid]
img_obj.manage_addProperty("entrytitle",posting_title,"string")
img_obj.manage_addProperty("entryid",str(new_id),"string")
except:
pass
#
# Validation/Sanitize
#
security.declareProtected(View, 'removeHTML')
def removeHTML(self,s):
"""Remove HTML tags."""
return remove_html(str(s))
security.declareProtected(View, 'validateHTML')
def validateHTML(self,s):
"""Remove HTML tags."""
return validate_html(str(s),tags)
security.declareProtected(View, 'validateEntryBody')
def validateEntryBody(self,s):
"""Remove HTML tags for Entry."""
tags = []
try:
tag_prop = self.getProperty(COREBlog.body_tags_id)
tags = split(tag_prop,",")
except:
pass
return validate_html(str(s),tags)
security.declareProtected(View, 'validateCommentBody')
def validateCommentBody(self,s):
"""Remove HTML tags for Comment."""
tags = []
try:
tag_prop = self.getProperty(COREBlog.comment_tags_id)
tags = split(tag_prop,",")
except:
pass
return validate_html(str(s),tags)
#
# misc. methods
#
security.declareProtected(View, 'convertCharcode')
def convertCharcode(self,s,tocode):
""" Converting charcode """
return convert_charcode(s,tocode)
security.declareProtected(View, 'get_charcode')
def get_charcode(self):
""" return charcode setting """
prop = self.getProperty("management_page_charset")
return prop
security.declareProtected(View, 'get_blogclient_charcode')
def get_blogclient_charcode(self):
""" return charcode setting for blogclient """
prop = self.getProperty("blogclient_char_code")
return prop
security.declareProtected(View, 'get_trackback_charcode')
def get_trackback_charcode(self):
""" return charcode setting """
prop = self.getProperty("trackback_char_code")
return prop
#
# XML-RPC Interfaces
#
#Blogger API
security.declarePrivate('name2category_id')
def name2category_id(self,cats):
""" Utility method to convert category name to category id """
c = convert_charcode
bc = self.get_blogclient_charcode()
cd = {}
#First, make category dictionary (name:id)
for cat in self.category_list():
cd[cat.name] = cat.id
ret_cl = []
for cname in cats:
if cd.has_key(cname):
ret_cl.append(cd[cname])
return ret_cl
security.declareProtected(ManageCOREBlog, 'newPost')
def newPost(self,appkey,blogid,username,password,
content,publish,REQUEST=None):
""" post new entry"""
#get entry
c = convert_charcode
bc = self.get_blogclient_charcode()
title,cats,body = parse_blogger_post(content)
cl = self.name2category_id(cats)
if not cl:
cl = [self.getProperty("blog_client_default_category")]
comment_status = comment_open
trackback_status = trackback_open
if not self.getProperty("allow_comment_moblog"):
comment_status = comment_none
if not self.getProperty("allow_trackback_moblog"):
trackback_status = trackback_none
#Post for MT compatibles
new_id = self.manage_addEntry(author=username,
body=c(body,self.get_charcode(),bc),
extend='',
excerpt='',moderated=publish,
main_category=cl[0],sub_category=cl[1:],
title=c(title,self.get_charcode(),bc),
subtitle='',format=format_html,
allow_comment=comment_status,
receive_trackback=trackback_status,
sendnow=1)
return str(new_id)
security.declareProtected(ManageCOREBlog, 'editPost')
def editPost(self,appkey,postid,username,password,
content,publish,REQUEST=None):
""" set entry informations (remapped from editPost)"""
import xmlrpclib
try:
int_id = int(postid)
#get entry
ent = self.getEntry(int_id)
c = convert_charcode
bc = self.get_blogclient_charcode()
ct = {}
title,cats,body = parse_blogger_post(content)
cl = self.name2category_id(cats)
if not cl:
cl = ent.entry_category_list()
#Post for MT compatibles
ent.manage_editEntry(author=ent.author,
body=c(body,self.get_charcode(),bc),
extend='',format=ent.format,
excerpt='',moderated=publish,
main_category=cl[0],sub_category=cl[1:],
title=c(title,self.get_charcode(),bc),
subtitle=ent.subtitle)
return xmlrpclib.True
except:
return xmlrpclib.False
security.declareProtected(ManageCOREBlog, 'deletePost')
def deletePost(self,appkey,postid,username,password,
publish,REQUEST=None):
""" delete entry """
import xmlrpclib
try:
int_id = int(postid)
#delete entry
self.deleteEntry(int_id)
return xmlrpclib.True
except:
return xmlrpclib.False
security.declareProtected(ManageCOREBlog, 'getRecentPosts')
def getRecentPosts(self,appkey,blogid,username,password,
numberOfPosts,REQUEST=None):
""" return recent posts """
import xmlrpclib
c = convert_charcode
bc = self.get_blogclient_charcode()
rl = []
for ent in self.rev_entry_items(count=numberOfPosts):
body = """