# -*- coding: utf-8 # $Id$ # # Copyright 2001, 2002 by IVA Team and contributors # # This file is part of IVA. # # IVA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # IVA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with IVA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Contains class WebtopFolder, which represents a folder in a user's webtop.""" __version__ = "$Revision$"[11:-2] from copy import copy from urllib import quote_plus, quote import Globals import time from input_checks import is_valid_title, is_valid_url, strip_all, is_valid_id from WebtopItem import WebtopItem from WebtopLink import WebtopLink from WebtopMemo import WebtopMemo from WebtopFile import WebtopFile from Cruft import Cruft #import Webtop import OFS from OFS.ObjectManager import checkValidId import FLE from TempObjectManager import TempObjectManager from AccessControl import ClassSecurityInfo from common import translate from common import perm_view, perm_edit, perm_manage, perm_add_lo #since webtopfolder doesn't have acquisition. we import it for adding wiki:( #very stupid work-around from Acquisition import aq_base as aqbase from Errors import FleError try: from Products.ZWiki.ZWikiPage import ZWikiPage USE_ZWIKI = 1 except: USE_ZWIKI = 0 import re # This class acts as a container to other WebtopItems and as the factory # object used to manipulate them. class WebtopFolder( WebtopItem, OFS.Folder.Folder, TempObjectManager, Cruft): """A folder in a Webtop.""" meta_type = "WebtopFolder" list_of_types=('WebtopFolder', 'WebtopLink', 'WebtopMemo', 'WebtopFile', 'GroupFolder', 'GroupFolderProxy', 'Portfolio', 'AssignmentProxy') security = ClassSecurityInfo() security.declareProtected(perm_view, 'index_html') def index_html(self, REQUEST=None): "Avaleht" if not self.hasPermissionToView(REQUEST): return REQUEST.RESPONSE.redirect(REQUEST.HTTP_REFERER) self.updateStat(REQUEST, 'foldersOpened') self.viewedObject(REQUEST, self.getRelativeURL(self)) return self.wt_index_html() def __init__(self, parent, name): """Construct the webtop folder object.""" WebtopItem.__init__(self,parent,name) #TempObjectManager.__init__(self) self.set_icon('images/folder_gif.gif') security.declarePrivate('manage_afterAdd') def manage_afterAdd(self,item,container): """Clean up creation - create the TempObjectManager and set permissions.""" try: WebtopItem.manage_afterAdd(self, item, container) except: pass # for ZCatalog security.declarePrivate('get_content') def get_content(self): """Return content (names of this folder's Webtop items in one string)""" tlist = ('WebtopFolder', 'WebtopLink', 'WebtopMemo', 'WebtopFile') if self.isFeatureEnabled('sqi'): tlist += ('WebtopProxyFile',) return ' '.join( [o.get_name() for o in self.objectValues(tlist)]) security.declareProtected(perm_view, 'has_content') def has_content(self): """Any WebtopItems in this folder?""" return len(self.objectIds(self.list_of_types)) > 0 security.declareProtected(perm_view, 'list_contents_request') def list_contents_request(self, REQUEST, extra=()): "jarjestab vastavalt Request parameeetrile suund" if hasattr(REQUEST, 'suund'): return self.list_contents(criteria=REQUEST['suund'], extra=extra) else: return self.list_contents(criteria='weight', extra=extra) security.declareProtected(perm_view, 'list_contents') def list_contents(self, criteria='',only_folder='', extra=()): """Returns a list of all different WebtopItems in this folder.""" if criteria == '': criteria = 'date' if self.isFeatureEnabled('sqi'): extra+= ('WebtopProxyFile',) if only_folder: objs = self.objectValues(only_folder) else: objs = self.objectValues(self.list_of_types+extra) if criteria == 'name': d = {} names = [] for o in objs: name = o.get_name() names.append(name) d[name] = o names.sort() s_objs = [] for n in names: s_objs.append(d[n]) return s_objs elif criteria == 'size': d = {} sizes = [] for o in objs: # We append name in order to get unique keys # 10 digits should be enough for everybody. :-) size = '%010d' % o.get_size() + o.get_name() sizes.append(size) d[size] = o sizes.sort() s_objs = [] for n in sizes: s_objs.append(d[n]) return s_objs elif criteria == 'date': d = {} timestamps = [] for o in objs: # We append name in order to get unique keys timestamp = '%012.4f' % o.get_timestamp() + o.get_name() timestamps.append(timestamp) d[timestamp] = o timestamps.sort() timestamps.reverse() s_objs = [] for n in timestamps: s_objs.append(d[n]) return s_objs elif criteria == 'weight': d = {} sizes = [] for o in objs: if not hasattr(o,'weight'): o.weight = 1000 size = '%010d' % o.weight + o.get_id() sizes.append(size) d[size] = o sizes.sort() sizes.reverse() s_objs = [] for n in sizes: s_objs.append(d[n]) return s_objs else: raise 'FLE Error', 'Unknown sort criteria' security.declareProtected(perm_view, 'juhtLeht') def juhtLeht(self): "Kataloogi avaleht kokkupakitavasse arhiivi" t="Kataloog" t=t+self.get_name()+"" return t security.declareProtected(perm_view, 'looArhiiv') def looArhiiv(self, REQUEST, arhiiv=None, tee=""): "Kataloogide ning alamkataloogide arhiveerimiseks." algus=0 import zipfile if arhiiv==None: import tempfile failinimi=tempfile.mktemp() arhiiv=zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED) algus=1 tee=tee+self.get_id()+"/" m=self.list_contents() kasIndeks=0 for x in m: if x.get_id()=="index.html": kasIndeks=1 if not kasIndeks: arhiiv.writestr(zipfile.ZipInfo(tee+"index.html"), self.juhtLeht()) for x in m: if x.meta_type=="WebtopFolder": x.looArhiiv(REQUEST, arhiiv, tee) if x.meta_type=="WebtopMemo": arhiiv.writestr(zipfile.ZipInfo(tee+x.get_id()+".txt"), x.get_body()) if x.meta_type=="WebtopFile": if x.has_realname(): arhiiv.writestr(zipfile.ZipInfo(tee+x.get_realname()), str(x.get_content())) else: arhiiv.writestr(zipfile.ZipInfo(tee+x.get_id()), str(x.get_content())) if algus: arhiiv.close() file = open(failinimi,"rb") export_data=file.read() file.close() import os os.remove(failinimi) REQUEST.RESPONSE.setHeader('content-type','application/zip') REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=arhiiv.zip') return export_data security.declareProtected(perm_view, 'puuSisu') def puuSisu(self,folder,level,t,res,url, REQUEST): #puu sisu teisest tasemest alates level = level + 1 t_tmp = 1 for w in folder.list_contents(only_folder = ('WebtopFolder','Portfolio','AssignmentProxy',), criteria='weight'): # def check_permission(self, REQUEST,permission,cuser=None,cobj=None): # TODO: check_permission here or other user will see your webtop folder hierarchy if w.kasWikiKaust(): continue if not w.check_permission(REQUEST, 'View'): continue path = str(t)+"-"+str(t_tmp) itf = w.puuSisu(w,level,path,'',url, REQUEST) res += "" res += ""+w.get_name()+"" res += "" res += "" res += itf itf = "" t_tmp = t_tmp + 1 return res security.declareProtected(perm_view, 'teePuu') def teePuu(self, REQUEST): # prints a nice tree of codes with relationships res = "
" level = 1 t = 1 #m_1 = getattr(self.fle_root().courses, self.jooksva_kursuse_nr(REQUEST)).gf for w in self.list_contents(only_folder = ('WebtopFolder','Portfolio','AssignmentProxy',), criteria='weight'): if w.kasWikiKaust(): continue if not w.check_permission(REQUEST, 'View'): continue itf = w.puuSisu(w,level,t,'',REQUEST.URL0, REQUEST) res += "" res += "" res += itf t = t + 1 res += "
" res += "
" res += ""+name+"" res += "
" res += "
" return res security.declareProtected(perm_edit, 'laeArhiiv') def laeArhiiv(self, REQUEST, arhiiviandmed, html_to_wiki='', wikifolder_name='WikiHTML'): """ Arhiivi laadimine kataloogi """ import tempfile import OFS.Image failinimi=tempfile.mktemp() fail=open(failinimi, "w+b") fail.write(arhiiviandmed.read()) fail.close() import zipfile arhiiv=zipfile.ZipFile(failinimi, "r", zipfile.ZIP_DEFLATED) m=arhiiv.namelist() viga = "" if html_to_wiki: if not wikifolder_name: wikifolder_name = 'WikiHTML' wf = self.add_wiki(wikifolder_name, 1) for x in m: if html_to_wiki: page_content = arhiiv.read(x) #page_name = x.split('.')[0].capitalize() page_name = x if page_name.endswith('.html'): #wikiobj = ZWikiPage(source_string='', __name__=page_name) wikiobj = ZWikiPage(source_string=page_content, __name__=page_name) #wikiobj._deleteOwnershipAfterAdd() #wikiobj.title='pealkiri' wf._setObject(page_name,wikiobj) wikiobj.setPageType('html') elif page_name.endswith('.jpg') or page_name.endswith('.gif') or page_name.endswith('.png'): # add image wf._setObject(page_name, OFS.Image.Image(page_name, page_name, page_content)) else: # add document wf._setObject(page_name, OFS.Image.File(page_name, page_name, page_content)) else: result = self.lisaFail(REQUEST, x, arhiiv) if not result: self.updateStat(REQUEST, 'uploadedFiles') else: viga += result import os os.remove(failinimi) return viga security.declareProtected(perm_edit, 'lisaFail') def lisaFail(self, REQUEST, failinimi, arhiiv=None): "Loob kataloogitee alates jooksvast kataloogist ning lõppu paigutab faili" kaust=self m=failinimi.split("/") vastus = "" for x in m[0:-1]: if not hasattr(kaust.aq_self, x): kaust.add_folder(x, x) kaust=getattr(kaust, x) try: checkValidId(kaust,m[-1],allow_dup=1) except: vastus += quote_plus(m[-1])+" - "+translate(self, 'Error: Invalid filename. Filename cannot contain spaces, punctuation symbols etc.', target=self.giveLanguage(REQUEST))+"
" try: if not vastus: checkValidId(kaust,m[-1]) kaust.add_file(m[-1], arhiiv.read(failinimi), m[-1]) except: vastus += quote_plus(m[-1])+" - "+translate(self, 'Error: Filename is already in use.',target=self.giveLanguage(REQUEST))+"
" return vastus security.declareProtected(perm_edit, 'add_wiki_handler') def add_wiki_handler( self, REQUEST, my_name, userLocation='', submit = '', # form buttons cancel = '', # ): """Handles the input from folder add form.""" my_name = strip_all(my_name) import string if my_name.upper() == 'WELCOME': return self.message_dialog_error( self, REQUEST, title = 'Invalid name', message = 'This is a reserved name, please pick another name.', action = 'wt_add_wiki?my_name=%s' % quote_plus(my_name)) viga = 0 try: my_name = string.replace(my_name,my_name[0],my_name[0].upper(),1) except IndexError: viga =1 #if submit: if not cancel: if not is_valid_id(my_name) or viga: return self.message_dialog_error( self, REQUEST, title='Invalid name', message='Give valid name', action='wt_add_wiki?my_name=%s' % quote_plus(my_name)) if my_name in [o.get_name() for o in self.list_contents()]: return self.message_dialog_error( self, REQUEST, title='Invalid name', message=translate(self,"Name '%s' taken",target=self.giveLanguage(REQUEST)) % my_name, action='wt_add_wiki?name=%s' % quote_plus(my_name), my_name=my_name) if not USE_ZWIKI: return self.message_dialog_error( title='ZWiki unavailable', message="ZWiki is not installed.", action="index_html") fold_obj = self.add_wiki(my_name) fold_obj.set_author(str(REQUEST.AUTHENTICATED_USER)) if userLocation == 'Bookshelf': self.updateStat(REQUEST, 'bookshelf') self.updateStat(REQUEST, 'createdWikis') elif cancel: pass else: # This code should never be reached. raise 'FLE Error', 'Unknown button' return REQUEST.RESPONSE.redirect('index_html') security.declareProtected(perm_edit, 'add_folder_handler') def add_folder_handler( self, REQUEST, my_name, submit = '', # form buttons cancel = '', # ): """Handles the input from folder add form.""" my_name = strip_all(my_name) #if submit: if not cancel: if not is_valid_title(my_name): return self.message_dialog_error( self, REQUEST, title='Invalid name', message='Give valid name', action='wt_add_folder?my_name=%s' % quote_plus(my_name)) if my_name in [o.get_name() for o in self.list_contents()]: return self.message_dialog_error( self, REQUEST, title='Invalid name', message=translate(self,"Name '%s' taken",target=self.giveLanguage(REQUEST)) % my_name, action='wt_add_folder?name=%s' % quote_plus(my_name), my_name=my_name) fold_obj = self.add_folder(my_name) fold_obj.set_author(str(REQUEST.AUTHENTICATED_USER)) elif cancel: pass else: # This code should never be reached. raise 'FLE Error', 'Unknown button' return REQUEST.RESPONSE.redirect('index_html') def kasWikiKaust(self,REQUEST=None): """ kas tegemist on wiki kaustaga """ if hasattr(self,'wiki_kaust'): if self.wiki_kaust == 1: return 1 return 0 security.declareProtected(perm_view, 'wikiKaustEsimeneLeht') def wikiKaustEsimeneLeht(self,REQUEST=None): """ find ZWikiPage that has no parents """ lehenimi = "" count = 0 if hasattr(self,'_v_cached_first_name'): if hasattr(self, self._v_cached_first_name): if REQUEST: self.viewedObject(REQUEST, self.getRelativeURL(self)) return self._v_cached_first_name if len(self.objectValues('ZWiki Page'))>0: pass else: return "../" for obj in self.objectValues('ZWiki Page'): if obj.parents == [] or obj.parents[0] == '': lehenimi = obj.__name__ self._v_cached_first_name = lehenimi count = count +1 if not lehenimi: if hasattr(self.aq_inner.aq_self, self.get_name()): lehenimi = self.get_name() if lehenimi and REQUEST: self.viewedObject(REQUEST, self.getRelativeURL(self)) return lehenimi security.declarePrivate('aq_base') def aq_base(self): return self.aqbase security.declareProtected(perm_edit, 'add_wiki') def add_wiki(self,name, folder_only=0): from Products.ZWiki.ZWikiPage import ZWikiPage """Implementation of add_folder_handler without http code.""" # wt2 = Webtop('sahtel').__of__(self) f = WebtopFolder(self,name) f.wiki_kaust = 1 while hasattr(self.aq_self, f.id): f.id = self.generate_id() self._setObject(f.id,f) if folder_only: return f.__of__(self) wikiobj = ZWikiPage(source_string='', __name__=name) #wikiobj._deleteOwnershipAfterAdd() #wikiobj.title='pealkiri' f._setObject(name,wikiobj) return f.__of__(self) security.declareProtected(perm_edit, 'add_folder') def add_folder(self,name,preferred_id=None): """Implementation of add_folder_handler without http code.""" f = WebtopFolder(self,name) if preferred_id: f.id = preferred_id while hasattr(self.aq_self, f.id): f.id = self.generate_id() self._setObject(f.id,f) return f.__of__(self) security.declareProtected(perm_edit, 'add_link_handler') def add_link_handler( self, REQUEST, my_name, url, type = '', userLocation='', submit = '', # form buttons cancel = '', # back_link = '', # 'add link to webtop' feature outside webtop ): """Handles the input from link add form.""" my_name = strip_all(my_name) if submit: if not is_valid_title(my_name): return self.message_dialog_error( self, REQUEST, title='Invalid name', message='Give valid name', action='wt_add_link?my_name=%s&my_url=%s' % \ (quote_plus(my_name), quote_plus(url))) elif my_name in [o.get_name() for o in self.list_contents()]: return self.message_dialog_error( self, REQUEST, title='Invalid name', message=translate(self,"Name '%s' taken",target=self.giveLanguage(REQUEST)) % my_name, action='wt_add_link?my_name=%s&url=%s' % \ (quote_plus(my_name), quote_plus(url))) if not is_valid_url(url): return self.message_dialog_error( self, REQUEST, title='Invalid URL', message='Invalid URL', action='wt_add_link?my_name=%s&url=%s' % \ (quote_plus(my_name), quote_plus(url))) link_obj = self.add_link(my_name, url) if userLocation == 'Bookshelf': self.updateStat(REQUEST, 'bookshelf') self.updateStat(REQUEST, 'linksAdded') link_obj.set_author(str(REQUEST.AUTHENTICATED_USER)) elif back_link: if not is_valid_title(my_name): return self.message_dialog( self, REQUEST, title='Invalid name', message='Give valid name', action=back_link) # I think raise is more appropriate here because # if we have invalid name here, we have a _bug_ # and not an user error. --jmp 2002-02-20 raise 'FLE Error', 'Invalid name for link.' # If name already exists generate a new name... my_name = self.__build_name(my_name) link_obj = self.add_link(my_name,url,1) link_obj.set_author(str(REQUEST.AUTHENTICATED_USER)) if REQUEST: return self.message_dialog( self, REQUEST, title='Webtop link added', message='Added webtop %s link %s' % (type, my_name), action=back_link) else: return elif cancel: pass else: # This code should never be reached. raise 'FLE Error', 'Unknown button' if REQUEST: REQUEST.RESPONSE.redirect('index_html') security.declarePrivate('add_link') def add_link(self,name,url_or_obj,internal=0): """Implementation of add_link_handler without http code.""" l = WebtopLink(self,name,url_or_obj,internal) while hasattr(self.aq_self, l.id): l.id = self.generate_id() self._setObject(l.id,l) return l.__of__(self) security.declarePrivate('add_group_folder_proxy') def add_group_folder_proxy(self, name, course_id): """Create GroupGolderProxy into WebtopFolder.""" from GroupFolderProxy import GroupFolderProxy uname = str(self.getOwner()) name = self.__build_name(name) l = GroupFolderProxy(self, name, course_id) self._setObject(l.id, l) l.changeOwnership(self.acl_users.getUser(uname).__of__(self.acl_users)) # Copy local roles that user (owner of the WebtopFolder) has # on the course to the GroupFolderProxy. (+ everybody should # own her own GroupFolderProxy!) for user, roles in self.courses.get_child(course_id).get_local_roles(): if uname == user: self.get_child(l.id).manage_setLocalRoles(uname, roles + ('Owner',)) return raise 'FLE Error', 'User does not have any role in the course!' security.declarePrivate('recursive_delete_group_folder_proxy') def recursive_delete_group_folder_proxy(self, course_id): """Delete all GroupFolderProxy objects (pointing to given course) in this folder and recursively in all subfolders.""" for proxy in self.objectValues('GroupFolderProxy'): if proxy.get_course_this_belongs_to().get_id() == course_id: self._delObject(proxy.get_id()) for folder in self.objectValues('WebtopFolder'): folder.recursive_delete_group_folder_proxy(course_id) security.declareProtected(perm_edit, 'add_file_handler') def add_file_handler( self, REQUEST, my_name, file=None, key = '', userLocation='', submit = '', # form buttons cancel = '', # ): """Handles the input from upload form.""" import Webtop nimetu=0 my_name = strip_all(my_name) if submit: quota = self.get_quota() if quota > 0: ui = getattr(self.fle_root().fle_users, str(REQUEST.AUTHENTICATED_USER)) quota = quota * len(ui.user_courses()) message = '' if self.absolute_url().find('fle_users')>=0: if quota >= 0: # Quota in use? # Would we exceed the quota? if file and len(file.filename): file.seek(0, 2) size = self.find_class_obj(Webtop.Webtop).get_size() + \ file.tell() file.seek(0, 0) if size > quota: return self.message_dialog_error( self, REQUEST, title='Quota reached', message='Quota reached', action='index_html') nimemassiiv=file.filename.split("\\") if len(my_name)==0: nimetu=1 my_name=nimemassiiv[-1] # Check name if not is_valid_title(my_name): message = translate(self,'Give valid name for ',target=self.giveLanguage(REQUEST))+'. ' elif my_name in [o.get_name() for o in self.list_contents()]: message = translate(self,"Name '%s' taken",target=self.giveLanguage(REQUEST)) % my_name elif not is_valid_id(my_name) and nimetu: message = translate(self,'Give valid name',target=self.giveLanguage(REQUEST))+'. ' # Check file if not key: if (not file) or len(file.filename) is 0: message += ' '+translate(self,'No files supplied',target=self.giveLanguage(REQUEST)) if message: if (not key) and file and len(file.filename) > 0: key = self.add_tmp_object(WebtopFile(self, 'spam', file)) if key: action = 'wt_upload?key=%s&my_name=%s' % \ (quote_plus(key), quote_plus(my_name)) else: action = 'wt_upload?my_name=%s' % quote_plus(my_name) return self.message_dialog_error( self, REQUEST, title='Error', message=message, action=action) else: if key: f = self.remove_tmp_object(key) f.set_name(my_name) self._setObject(f.id,f) f.set_author(str(REQUEST.AUTHENTICATED_USER)) else: if nimetu: file_obj = self.add_file(nimemassiiv[-1], file, nimemassiiv[-1]) else: file_obj = self.add_file(my_name,file, nimemassiiv[-1]) file_obj.set_author(str(REQUEST.AUTHENTICATED_USER)) if userLocation == 'Bookshelf': self.updateStat(REQUEST, 'bookshelf') self.updateStat(REQUEST, 'uploadedFiles') elif cancel: if key: self.remove_tmp_object(key) else: # This code should never be reached. raise 'FLE Error', 'Unknown button' REQUEST.RESPONSE.redirect('index_html') security.declarePrivate('add_file') def add_file(self, name, file, original_name=''): """Implementation of add_file_handler without http code.""" f = WebtopFile(self, name, file, original_name) while hasattr(self, f.id): f.id = self.generate_id() self._setObject(f.id,f) return f.__of__(self) security.declareProtected(perm_edit, 'add_memo_handler') def add_memo_handler( self, REQUEST, my_name, contents, course_id=0, userLocation='', submit='', cancel=''): """Handles the input from memo add form.""" my_name = strip_all(my_name) if submit: if not is_valid_title(my_name): return self.message_dialog_error( self, REQUEST, title='Invalid name', message='Give valid name', action='wt_add_memo?my_name=%s&contents=%s' % \ (quote_plus(my_name), quote_plus(contents))) elif my_name in [o.get_name() for o in self.list_contents()]: return self.message_dialog_error( self, REQUEST, title='Invalid name', message=translate(self,"Name '%s' taken",target=self.giveLanguage(REQUEST)) % my_name, action='wt_add_memo?my_name=%s&contents=%s' % \ (quote_plus(my_name), quote_plus(contents)), my_name=my_name, contents=contents) else: memo_obj = self.add_memo(my_name,contents) memo_obj.set_author(str(REQUEST.AUTHENTICATED_USER)) if userLocation == 'Bookshelf': self.updateStat(REQUEST, 'bookshelf') self.updateStat(REQUEST, 'memosAdded') elif cancel: pass else: # This code should never be reached. raise 'FLE Error', 'Unknown button' REQUEST.RESPONSE.redirect('index_html') security.declarePrivate('add_memo') def add_memo(self,name,contents): """Implementation of add_memo_handler without http code.""" m = WebtopMemo(self,name,contents) while hasattr(self, m.id): m.id = self.generate_id() self._setObject(m.id,m) return m.__of__(self) security.declareProtected(perm_edit, 'form_handler') def form_handler( self, item_ids=None, copy='', cut='', paste='', remove='', rename='', # submit buttons kalendrisse='', paki='', arhiivifail=None, lae='', REQUEST=None, cancel='', paki2='',userLocation='', html_to_wiki='', wikifolder_name=''): """Handles the input from folder default form: item copy/cut/paste, remove and rename operations.""" # Quota reached? (GroupFolders don't use quota.) import common if cancel: REQUEST.RESPONSE.redirect('index_html') return try: quota_limit_reached = self.is_quota_limit_reached(REQUEST) except AttributeError: quota_limit_reached = 0 if not common.intersect_bool( ('GroupFolder', 'GroupFolderProxy'), [t[0].meta_type for t in self.list_parents_to_top()]) \ and quota_limit_reached and (copy or cut or paste): if REQUEST: return self.message_dialog_error( self, REQUEST, title=translate(self,'Quota reached',target=self.giveLanguage(REQUEST)), message=translate(self,'Quota reached',target=self.giveLanguage(REQUEST)), action='index_html') else: raise 'FLE Error', \ "Can't copy/cut/paste when quota is reached." if item_ids is None and paste or paki or lae: if paste: self.pasteNG(REQUEST) elif paki: if paki2: return self.looArhiiv(REQUEST) else: REQUEST.RESPONSE.redirect('wt_manage?userLocation='+userLocation) return elif lae: tulem = self.laeArhiiv(REQUEST, arhiivifail, html_to_wiki, wikifolder_name) if userLocation == 'Bookshelf': self.updateStat(REQUEST, 'bookshelf') if tulem: return self.message_dialog_error(self,REQUEST, title='Error: Some files failed!', message=tulem, width=600, align='left') return tulem elif item_ids: from types import StringType if type(item_ids) is StringType: item_ids=(item_ids,) objs = self.map_ids_to_objects(item_ids) if remove: return self.message_dialog2( self, title="Confirmation", message=translate(self,"Are you sure you want to delete these items: ",target=self.giveLanguage(REQUEST)) + ' ' + ', '.join([ci.get_name() for ci in objs]), handler = "remove_helper", extra_value_name="item_ids", extra_values=item_ids, option1_value="Cancel", option1_name="cancel", option2_value="Delete", option2_name="delete" ) elif copy: self.copy_n_cutNG(REQUEST, objs, 'copy') elif cut: self.copy_n_cutNG(REQUEST, objs, 'cut') elif kalendrisse: self.kalendrisse(REQUEST, objs) elif rename: REQUEST.set('item_ids',item_ids) return self.wt_rename(REQUEST) else: raise 'No action specified!' else: if REQUEST: return self.message_dialog_error( self, REQUEST, title='No items selected', message='Select item first', action='index_html') if not kalendrisse: REQUEST.RESPONSE.redirect('index_html') # FIXME: input_checks security.declareProtected(perm_edit, 'rename_helper') # This is called from wt_rename to convert a list stored in url # back to list. There are two cases: # # 1. User select some object on index_html page and clicks 'rename': # # index_html(dtml) -> form_handler -> redirect to wt_rename(dtml) # # In this case only Ids of objects are passed to form_handler # # # 2. As long user gives invalid input we are in the following loop: # # wt_rename -> rename_handler -> message_dialog(dtml) -> wt_rename # # Here we have pass user's invalid names back to wt_rename so # that user doesn't have to start everytime from scratch. def rename_helper(self, expr1, expr2=None): """Helper function for DTML method wt_rename.dtml""" if not expr2: return eval(expr1) else: id_list = eval(expr1) name_list = eval(expr2) retval = [] for i in range(len(id_list)): retval.append((id_list[i], name_list[i])) return retval security.declarePrivate('copy_n_cutNG') def copy_n_cutNG(self, REQUEST, items, operation='copy'): """ Saves items physical paths for later pasting """ locations = [] operation = 'iva_'+operation+'_items' for item in items: pp = item.getPhysicalPath() item_location = '/'.join(pp[1:]) #locations.append(item_location) locations.append(pp) REQUEST.SESSION.set('iva_cut_items', [] ) REQUEST.SESSION.set('iva_copy_items', [] ) REQUEST.SESSION.set(operation, locations) return 0 security.declareProtected(perm_edit, 'kalendrisse') def kalendrisse(self, REQUEST, items): "Viide sündmusena kalendrisse" import Kalender #XXX: which calendar? from Kalender import KalendriSyndmus k=self.getCalendar() esimene=None for e in items: s=e.absolute_url()[len(self.fle_root().absolute_url()):] nr=str(k.kysiUusNr()) s=KalendriSyndmus(e.get_name(), siseviide=s) s.id=nr k._setObject(nr, s) if esimene==None: esimene=s if esimene: REQUEST.RESPONSE.redirect(k.absolute_url()+"/"+nr+"/changeEvent") def __build_name(self,name, REQUEST): """Constructs a name for an item pasted from the clipboard. If the item's own name is already used, a suitable postfix is added.""" if not self.name_exists(name): return name iter = 1 newname=name+' ('+translate(self,'Copy1',target=self.giveLanguage(REQUEST))+')' while self.name_exists(newname): iter += 1 newname=name+' ('+translate(self,'Copy2',target=self.giveLanguage(REQUEST))+' ' + str(iter) + ')' return newname security.declarePrivate('do_pasting') def do_pasting(self, REQUEST, obj_url): """ gets old objects, makes copy and puts it in to new location """ olditem = self.restrictedTraverse(obj_url) newitem = olditem._getCopy(self) newitem.id = self.generate_id() newitem.set_name(self.__build_name(newitem.get_name(), REQUEST)) self._setObject(newitem.id, newitem) return olditem, newitem security.declarePrivate('pasteNG') def pasteNG(self, REQUEST): """ gets objects urls from iva_copy_items or/and iva_cut_items and pastes """ for obj_url in REQUEST.SESSION.get('iva_copy_items', []): self.do_pasting(REQUEST, obj_url) for obj_url in REQUEST.SESSION.get('iva_cut_items', []): olditem, newitem = self.do_pasting(REQUEST, obj_url) if olditem and newitem: oldfolder = olditem.parent() oldfolder._delObject(olditem.id) REQUEST.SESSION.set('iva_cut_items', [] ) #REQUEST.SESSION.set('iva_copy_items', [] ) return 0 security.declareProtected(perm_edit,'remove_helper') def remove_helper(self, REQUEST,item_ids, delete='', cancel=''): """ helps remove """ if cancel: return REQUEST.RESPONSE.redirect('index_html') if delete: objs = self.map_ids_to_objects(item_ids) self.remove(objs) return REQUEST.RESPONSE.redirect('index_html') security.declarePrivate('remove') # items: list of removable object references in current def remove(self,items): """Removes items from this folder, placing them in trash. Or actually: in the tmp_objects folder inside this WebtopFolder.""" for item in items: # self.move_to_tmp(item) self._delObject(item.get_id()) security.declareProtected(perm_edit, 'rename_handler') def rename_handler( self, REQUEST, item_id_list, new_name_list, submit = '', # form buttons cancel = '', # ): """Handles rename_form submission.""" if submit: bad_names = [] for name in new_name_list: if not is_valid_title(name): bad_names.append(name) if bad_names: return self.message_dialog_error( self, REQUEST, title='Invalid name', message=translate(self,'The following names are invalid:',target=self.giveLanguage(REQUEST)) + ' %s' % \ " ".join([repr(n) for n in bad_names]), action='index_html')#&names=%s'#% \ # (quote(repr(item_id_list)), # quote(repr(new_name_list)))) # Same name given for several object? new_names = list(copy(new_name_list)) new_names.sort() for i in range(len(new_names)-1): if new_names[i] == new_names[i+1]: return self.message_dialog_error( self, REQUEST, title='Invalid name', message='You gave the same name for several objects.', action='index_html')# % \ # (quote(repr(item_id_list)), # quote(repr(new_name_list)))) # Some other object has already some given name? # FIXME: slow: 'not in' inside loop... names_in_use = [o.get_name() for o in \ filter(lambda x, y=item_id_list: \ x.get_id() not in y, self.list_contents())] bad_names = [] for name in new_name_list: if name in names_in_use: bad_names.append(name) if bad_names: REQUEST.set('item_ids',item_id_list) return self.message_dialog_error( self, REQUEST, title='Invalid name', message=translate(self,'The following names are already in use:',target=self.giveLanguage(REQUEST)) + ' %s' % \ " ".join([repr(n) for n in bad_names]), action='index_html')# \ # (quote(repr(item_id_list)), # quote(repr(new_name_list)))) for i in range(len(item_id_list)): (id, name) = (item_id_list[i], new_name_list[i]) self.rename(self.get_child(id), name) elif cancel: pass else: # This code should never be reached. raise 'FLE Error', 'Unknown button' REQUEST.RESPONSE.redirect('index_html') security.declarePrivate('name_exists') def name_exists(self,name): """Checks whether a given name exists already in the folder.""" for item in self.objectValues(): if hasattr(item,'get_name'): if item.get_name()==name: return 1 return 0 security.declarePrivate('rename') # Input checks are done in rename_handler. def rename(self,objref,new_item_name): """Implementation of item rename.""" objref.set_name(new_item_name) security.declareProtected(perm_view, 'get_size') def get_size(self): """Return size of the object.""" size = 0 for o in self.objectValues( ('WebtopFolder', 'WebtopLink', 'WebtopMemo', 'WebtopFile')): size += o.get_size() return size security.declareProtected(perm_view, 'lastModification') def lastModification(self): "Viimane muutus andmepuus" time = self.get_timestamp() for o in self.objectValues( ('WebtopFolder', 'WebtopLink', 'WebtopMemo', 'WebtopFile','Subgroup', 'Portfolio')): if o.get_timestamp()>time: time = o.viimaneMuutus() return time security.declareProtected(perm_view, 'getWebtopRoot') def getWebtopRoot(self): """ return webtop """ if hasattr(self, 'toplevel'): return self while 1: x = self.aq_parent if x == self.fle_root(): return self if hasattr(x, 'toplevel'): return x security.declareProtected(perm_edit, 'add_portfolio') def add_portfolio(self): """ create portfolio """ import Portfolio o = Portfolio.Portfolio(self, 'Portfolio') self._setObject(o.id, o) return o.__of__(self) security.declareProtected(perm_edit, 'import_form_handler') def import_form_handler(self, REQUEST, file='', wikionly='', cancel='', course_import='', wiki_koht=''): """ import zwikis. wt_manage """ uname = REQUEST.AUTHENTICATED_USER.getUserName() right = 0 if file and wikionly and course_import and wiki_koht: right = 1 if not right: raise '' from ImportExportIMS import Importer import tempfile, os from StringIO import StringIO out = StringIO() koht=wiki_koht[len(self.fle_root().absolute_url()):].split('/') m = self.fle_root() for x in koht: if x: m = getattr(m, x) koht = m filename = tempfile.mktemp() f = open(filename,"w+b") f.write(file.read()) f.close() import_data=None jnr = None try: jnr = self.get_course_id_from_req(REQUEST) except AttributeError: jnr = self.get_jooksev_kursus() imported = Importer(uname,self.fle_root(),'',getattr(self.fle_root().courses, jnr),userwikionly=koht, out=out) imported.loadZip(filename) element = imported.loadFile('imsmanifest.xml') imported.processFile(self,element) os.remove(filename) return REQUEST.RESPONSE.redirect(wiki_koht) Globals.InitializeClass(WebtopFolder) # EOF