TurboGears and MoinMoin

9 views
Skip to first unread message

percious

unread,
Jun 5, 2006, 12:13:59 PM6/5/06
to TurboGears
Anyone tried integrating the two?

We are in the process if anyone is interested in the end result, or
contributing.

-chris

percious

unread,
Jun 5, 2006, 1:15:28 PM6/5/06
to TurboGears
One person has responded anonymously, so I will address his questions
(which are very good) here.

What have you already done?

We have the GUI editor running with 75% of the functionality working
properly. It does save pages to the File MoinMoinDB.

We have the Page grabbed from MoinMoin displaying with formatted html.

What are your plans?

Indexing. Using MoinMoin, and subclassed for our own use.
Templates.
NewPage.

Our ulitmate plan is to have our own set of pages which have MoinMoin
"modules" built into them, so you can edit sub-sections of pages. The
information for the back end will be stored using SQLObject or
SQLAlchemy.

What is currently being worked (I add)?
Previewing
Text Editing (probably next)

-chris

mahongquan

unread,
Jun 5, 2006, 10:15:16 PM6/5/06
to TurboGears
i am interest in integating moinmoin in turbogears.
some month ago, i managed to run moinmoin over turbogears.but have
small bug.
below is my code.

# -*- coding: iso-8859-1 -*-
from MoinMoin import config
from MoinMoin.request import RequestBase
import cherrypy
def getdict(d,s,default):
try:
r=d[s]
except KeyError,e:
r=default
return(r)
class WikiRoot:
def index(self,*arg,**karg):
req = RequestCherry(cherrypy,arg,karg)
req.run()
return(req.output())
index.exposed=True
def default(self,*arg,**karg):
req = RequestCherry(cherrypy,arg,karg)
req.run()
return(req.output())
default.exposed=True
class RequestCherry(RequestBase):
def cherryUri(self):
p=self.cpresponse.path.split("/")
p=p[:-1]
for p1 in p:
r="/"+p1
return r
def output(self):
return(self.res[0])
def __init__(self, cpm,arg,karg):
if len(arg)>0:
pagename=arg[0]
else:
pagename=""
properties={}
self.res=[""]
self.arg=arg
self.karg=karg
self.cpresponse = cpm.request
self.reactor= cpm.response
self.http_accept_language =
getdict(self.cpresponse.headerMap,'Accept-Language','')
self.saved_cookie =
getdict(self.cpresponse.headerMap,'Cookie','')
self.http_user_agent = self.cpresponse.headerMap['User-Agent']

self.server_name =
self.cpresponse.headerMap['Host'].split(':')[0]
hp=self.cpresponse.headerMap['Host'].split(':')
if (len(hp)==2):
self.server_port = hp[1]
else:
self.server_port = "80"
self.is_ssl = 0
self.path_info = '/' + '/'.join([pagename]) #+
self.cpresponse.postpath)
self.request_method =self.cpresponse.method
self.remote_host = self.cpresponse.remoteHost
self.remote_addr = self.cpresponse.remoteAddr
self.script_name = self.cherryUri()
self.request_uri = self.cpresponse.path

# Values that need more work
self.query_string = self.splitURI(self.request_uri)[1]
#self.setHttpReferer(self.cpresponse.getHeader('Referer'))
self.setHost()

self.setURL(self.cpresponse.headerMap)#self.cpresponse.getAllHeaders()

self.debugEnvironment(self.cpresponse.headerMap)

RequestBase.__init__(self, properties)
def run(self):
""" Handle delayed errors then invoke base class run """
if hasattr(self, 'delayedError'):
self.fail(self.delayedError)
return self.finish()
RequestBase.run(self)

def setup_args(self, form=None):
""" Return args dict

Cherry already parsed args, including __filename__ hacking,
but did not decoded the values.
"""
#return self.decodeArgs(self.cpresponse.args)
from types import InstanceType,StringType
a={}
try:
a=self.karg
for a1 in a:
r=[]
if type(a[a1])==StringType:
r.append(unicode(a[a1],"utf-8"))
elif type(a[a1])==InstanceType:
r.append(a[a1].file.read())
else :
r.append(a[a1])
a[a1]=r
except IndexError,e:
pass
return(a)

def read(self, n=None):
""" Read from input stream.
"""
# XXX why is that wrong?:
#rd = self.reactor.callFromThread(self.cpresponse.read)

# XXX do we need self.reactor.callFromThread with that?
# XXX if yes, why doesn't it work?
self.cpresponse.content.seek(0, 0)
if n is None:
rd = self.cpresponse.content.read()
else:
rd = self.cpresponse.content.read(n)
#print "request.RequestCherry.read: data=\n" + str(rd)
return rd

def write(self, *data):
d=self.encode(data)
self.res[0]=self.res[0]+d
def flush(self):
pass # XXX is there a flush in Cherry?

def finish(self):
RequestBase.finish(self)
#self.reactor.callFromThread(self.cpresponse.finish)

def open_logs(self):
return
# create log file for catching stderr output
if not self.opened_logs:
sys.stderr = open(os.path.join(self.cfg.data_dir,
'error.log'), 'at')
self.opened_logs = 1

# Headers
----------------------------------------------------------

def __setHttpHeader(self, header):
if type(header) is unicode:
header = header.encode('ascii')
key, value = header.split(':',1)
value = value.lstrip()
if key.lower() == 'set-cookie':
key, value = value.split('=',1)
self.cpresponse.simpleCookie[key]=value
#self.cpresponse.addCookie(key, value)
else:
self.reactor.headerMap[key]=value
#print "request.RequestCherry.setHttpHeader: %s" % header

def http_headers(self, more_headers=[]):
if getattr(self, 'sent_headers', None):
return
self.sent_headers = 1
have_ct = 0

# set http headers
for header in more_headers + getattr(self, 'user_headers', []):
if header.lower().startswith("content-type:"):
# don't send content-type multiple times!
if have_ct: continue
have_ct = 1
self.__setHttpHeader(header)

if not have_ct:
self.__setHttpHeader("Content-type: text/html;charset=%s" %
config.charset)

def http_redirect(self, url):
""" Redirect to a fully qualified, or server-rooted URL

@param url: relative or absolute url, ascii using url encoding.
"""
url = self.getQualifiedURL(url)
raise cherrypy.HTTPRedirect(url)
#raise MoinMoinNoFooter

def setResponseCode(self, code, message=None):
#self.cpresponse.setResponseCode(code, message)
pass

percious

unread,
Jun 6, 2006, 8:18:08 AM6/6/06
to TurboGears
Interesting approach, significantly different from ours.

Our approach is to integrate MoinMoin module-wise. What this means is
that every web page served by the "controller" is served with a series
of modules that can be edited with the MoinMoin environment. This
means that there is a separate MM page that you can look at for each
module.

The reason for doing this is that I want the ability to control which
users can edit which parts of the page. I also like the history and
comparison features that MM offers, but I don't like how it only
handles 1 page in entirety. Looking at the way Wikipedia handles a
page, I think it works out pretty well having separate sections, and it
is absolutely essential for security in our application.

I would love to share our source code, but as of now, I cannot because
I have to check through Legal before I go and open source it.

Thanks for the interest, and I hope that we can colaborate in the
future.

-chris

Damjan

unread,
Jun 6, 2006, 8:35:34 AM6/6/06
to TurboGears
> The reason for doing this is that I want the ability to control which
> users can edit which parts of the page. I also like the history and
> comparison features that MM offers, but I don't like how it only
> handles 1 page in entirety. Looking at the way Wikipedia handles a
> page, I think it works out pretty well having separate sections, and it
> is absolutely essential for security in our application.

I think Moin can include other pages in its pages... Not the same, but
similar.

percious

unread,
Jun 6, 2006, 10:50:41 AM6/6/06
to TurboGears

This is great, we will probably use this feature, but we also have some
other stuff that is generated from a database to use.

-chris

mrclean

unread,
Jun 7, 2006, 9:30:00 AM6/7/06
to TurboGears
mahongquan wrote:
> i am interest in integating moinmoin in turbogears.
> some month ago, i managed to run moinmoin over turbogears.but have
> small bug.
> below is my code.

*Code Omitted*


Hello ... I'm working with percious on the MoinMoin integration.
Currently, I'm working on uploading and displaying images. Have you
made any progress integrating the MoinMoin utilities for these
functions or did you write you own?

Specifically, I'm interested in how MoinMoin delivers the image to the
webpage. They seem to pull the image into python and return it in some
fashion as opposed to linking to it directly. If you could tell me
where in the MoinMoin source code this is happening, that would be a
big help.

Thanks

percious

unread,
Jun 16, 2006, 10:05:48 AM6/16/06
to TurboGears
Ok, So it is all finished. We are going to have to put it through
legal if we want to open souce this. Couple of hints: MM does most of
the work, we just wrap it. The solution is about 150 lines of code.
If you wanted to use MM in your page it would be as simple as typing:

from MoinMoinComponent() import MoinMoinComponent()

MoinMoinComponent = MoinMoinComponent(), and refering to
MoinMoinComponent in an Iframe.

If anyone knows how to apply a CSS file directly to a <div> it would be
valuable.

The amount of interest generated will dictate the lengths to which we
try and get this open-sourced.

-chris

Jorge Vargas

unread,
Jun 16, 2006, 10:19:41 AM6/16/06
to turbo...@googlegroups.com

if you give me a copy I'll try it hehehe :)
no really if you could post a sample app so people could poke around it will drive some attention

-chris





Damjan

unread,
Jun 16, 2006, 11:32:08 PM6/16/06
to TurboGears
Well ther is a lot of interest for this... at least from me :)

Please do opensource it... who knows you might get valuable feedback,
bug reports and patches .

Reply all
Reply to author
Forward
0 new messages