CherryPy Project Download

FckeditorModule: fckeditor.py

Line 
1
2 from cherrypy.lib import httptools
3 import os.path
4 import os
5 from cherrypy import cpg
6
7 import mimetypes
8
9
10 contenthomedir='content/' #path were your page created with FCKeditor will reside
11 fckeditorhomedir="FCKeditor/" #Path where FCKeditor resides
12 imageshomedir="images/" #don't forget to create this folder for images
13 #WARNING: adapt your config.conf accordingly
14
15
16
17 def normpath(path):
18     "Just to avoid malicious urls ;-)"
19     path=path.replace('..','')
20     path=os.path.normpath(path)
21     return path
22    
23 class Editor:
24     def add(self,page=None):
25         "Just to add a page. Require page paramter"
26         if not page: return
27         return template % {'content':'','page':page}       
28     add.exposed=True
29    
30     def save(self,FCKeditor1,page):
31         "Save the generate html page with FCKeditor and immediately redirect to root page"
32         page=normpath(page)
33         fpath=contenthomedir+page
34         if not os.path.isdir(os.path.dirname(fpath)):
35             os.makedirs(os.path.dirname(fpath))
36         fid=open(fpath,'w')
37         fid.write(FCKeditor1)
38         fid.close()
39         httptools.redirect('/')
40     save.exposed=True
41    
42     def edit(self,page):
43         "edit an exisiting page that must reside in <contenthomedir>"
44         page=normpath(page)
45         fpath=contenthomedir+page
46         if not os.path.isfile(fpath):
47             return "The page %s is not existing" % fpath
48         content=open(fpath).read()
49         content=content.replace("\'","\\'")
50         return template % {'content':content,'page':page}
51     edit.exposed=True
52        
53     def default(self,*lw,**kw):
54         "Method to just display your created web pages"
55         path=normpath('/'.join(lw))
56         return open(contenthomedir+path).read()
57     default.exposed=True
58    
59     def connector(self,*lw,**kw):
60         "Required method by FCKeditor"
61         res=""
62         if kw.has_key('Command') and kw['Command']=='GetFoldersAndFiles':
63             cpg.response.headerMap['Content-Type']='text/xml'
64             cpg.response.headerMap['Cache-Control']='no-store, no-cache, must-revalidate'
65             cpg.response.headerMap['Pragma']='no-cache'
66             kw['imageshomedir']=imageshomedir
67             res="""<?xml version="1.0" encoding="utf-8" ?>
68                     <Connector command="%(Command)s" resourceType="%(Type)s">
69                      <CurrentFolder path="%(CurrentFolder)s" url="/%(imageshomedir)s%(CurrentFolder)s" /> """ % kw
70             fpath=kw['CurrentFolder']
71             if fpath[0]=='/': fpath=fpath[1:]
72             fdirpath=os.path.join(imageshomedir,fpath)
73             tmpfoldersxml=""
74             tmpfilesxml=""
75             for elem in os.listdir(fdirpath):
76                 fpath=os.path.join(fdirpath,elem)
77                 if os.path.isdir(fpath):
78                     #TODO: convert elem to xml string
79                     tmpfoldersxml+="""<Folder name="%s" />""" % (elem)
80                 elif os.path.isfile(fpath):
81                     #TODO: convert elem to xml string
82                     tmpfilesxml+="""<File name="%s" size="%s" />""" % (elem,os.stat(fpath)[6]/1024)
83             res+="""<Folders>%s</Folders>""" % tmpfoldersxml
84             res+="""<Files>%s</Files>""" % tmpfilesxml
85             res+="</Connector>"
86        
87         if kw.has_key('Command') and kw['Command']=='GetFolders':
88             cpg.response.headerMap['Content-Type']='text/xml'
89             cpg.response.headerMap['Cache-Control']='no-store, no-cache, must-revalidate'
90             cpg.response.headerMap['Pragma']='no-cache'
91             kw['imageshomedir']=imageshomedir
92             res="""<?xml version="1.0" encoding="utf-8" ?>
93                     <Connector command="%(Command)s" resourceType="%(Type)s">
94                      <CurrentFolder path="%(CurrentFolder)s" url="/%(imageshomedir)s%(CurrentFolder)s" /> """ % kw
95             fpath=kw['CurrentFolder']
96             if fpath[0]=='/': fpath=fpath[1:]
97             fdirpath=os.path.join(imageshomedir,fpath)
98             tmpxml=""
99             for elem in os.listdir(fdirpath):
100                 fpath=os.path.join(fpath,elem)
101                 if os.path.isdir(fpath):
102                     #TODO: convert elem to xml string
103                     tmpxml+="""<Folder name="%s" />""" % (elem)
104             res+="""<Folders>%s</Folders>""" % tmpxml
105             res+="</Connector>"
106        
107         if kw.has_key('Command') and kw['Command']=='FileUpload':
108             errorcode=0
109             #TODO: manage error code
110             filename=cpg.request.filenameMap.get('NewFile',os.tempnam('.','tmp'))
111             fdirpath=kw.get('CurrentFolder','')
112             if fdirpath[0]=='/': fdirpath=fdirpath[1:]
113             fdirpath=os.path.join(imageshomedir,fdirpath)
114             fid=open(os.path.join(fdirpath,filename),'wb')
115             fid.write(kw['NewFile'])
116             fid.close()
117             res="""<script type="text/javascript">"""
118             res+="""window.parent.frames["frmUpload"].OnUploadCompleted(%s,"%s") ;""" % (errorcode,filename)
119             res+="</script>"
120         if kw.has_key('Command') and kw['Command']=='CreateFolder':
121             cpg.response.headerMap['Content-Type']='text/xml'
122             cpg.response.headerMap['Cache-Control']='no-store, no-cache, must-revalidate'
123             cpg.response.headerMap['Pragma']='no-cache'
124             #TODO: manage errors
125             errorcode=0
126             errormsg=""
127             curdir=kw['CurrentFolder']
128             if curdir[0]=='/': curdir=curdir[1:]
129             fdirpath=os.path.join(imageshomedir,curdir,kw['NewFolderName'])
130             os.mkdir(fdirpath)
131             res="""'<Error number="%s" originalDescription="%s" />""" % (errorcode,errormsg)
132         if res:
133             return res
134     connector.exposed=True
135    
136 template="""
137 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
138 <html>
139         <head>
140                 <title>FCKeditor - Sample</title>
141                 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
142                 <meta name="robots" content="noindex, nofollow">
143                 <link href="/fck/_samples/sample.css" rel="stylesheet" type="text/css" />
144                 <script type="text/javascript" src="/fck/fckeditor.js"></script>
145                 <script type="text/javascript">
146
147 function FCKeditor_OnComplete( editorInstance )
148 {
149         window.status = editorInstance.Description ;
150 }
151
152                 </script>
153
154         </head>
155         <body>
156                 <h1>FCKeditor - Javascript</h1>
157                 <hr>
158                 <form action="/editor/save" method="post">
159                         <script type="text/javascript">
160 <!--
161 // Automatically calculates the editor base path based on the _samples directory.
162 // This is usefull only for these samples. A real application should use something like this:
163 // oFCKeditor.BasePath = '/fckeditor/' ;        // '/fckeditor/' is the default value.
164 //var sBasePath = document.location.pathname.substring(0,document.location.pathname.lastIndexOf('_samples')) ;
165
166 var oFCKeditor = new FCKeditor( 'FCKeditor1' ) ;
167 oFCKeditor.BasePath     = '/fck/' ;
168 oFCKeditor.Height = 400 ;
169 oFCKeditor.Value        = '%(content)s' ;
170 oFCKeditor.Create() ;
171 //-->
172                         </script>
173                         <br>
174                         <input type="hidden" name="page" value="%(page)s" />
175                         <input type="submit" value="Submit" />
176                 </form>
177         </body>
178 </html>
179 """
180
181 class FCK:
182     def default(self,*lw,**kw):
183         "This is a twist to provide static content of FCKeditor-2.0RC2 which contains ? and & characters and should not"
184         page=fckeditorhomedir+os.sep.join(lw)
185         # Set content-type based on filename extension
186         i = page.rfind('.')
187         if i != -1:
188             ext = page[i:]
189         else:
190             ext = ""
191         contentType = mimetypes.types_map.get(ext, "text/plain")
192         cpg.response.headerMap['Content-Type'] = contentType
193         return open(page,'rb').read()
194     default.exposed= True
195
196
197
198
199 if __name__=="__main__":
200     class Root:
201         def index(self):
202             return """<html><body>
203                    To create your fisrt page: <a href="editor/add?page=test.html">here</a><br>
204                    Then you can view the result <a href="content/test.html">here</a><br>
205                    Then you can edit it: <a href="editor/edit?page=test.html">here</a>
206                    </body></html>"""
207         index.exposed=True
208     cpg.root=Root()
209     cpg.root.editor=Editor()
210     cpg.root.fck=FCK() #according to <Template> FCKeditor is visible via /fck
211     cpg.server.start(configFile='config.conf')
212     #You should have a config.conf like following:
213     #[staticContent]
214     #content=content
215     #images=images

Hosted by WebFaction

Log in as guest/cherrypy to create/edit wiki pages