wiki.py :  » Wiki » Cloud-Wiki » cloudwiki-2.1 » cloud_wiki » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Wiki » Cloud Wiki 
Cloud Wiki » cloudwiki 2.1 » cloud_wiki » wiki.py
# Copyright (C) 2004 Scott W. Dunlop <sdunlop at users.sourceforge.net>
# 
# This program 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.
# 
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

import os, sys

from traceback import format_exception,print_exception
from database import Database,DatabaseError
from server import Server,Response
from authenticator import NoneAuthenticator,authentication_schemes
from interface import collate_interfaces,create_interface,load_gateway,load_method
from exceptions import KeyError,ValueError,OSError
from errors import *

from types import StringType

class Wiki( object ):
    __slots__ = (
        'server', 'database', 'logFile', 'siteName', 'stylesheetPath',
        'flagCacheStylesheets', 'authenticator', 'baseUrl', 'httpPort',
        'method_interfaces', 'gateway_interfaces', 'lexicon', 'stylesheet'
    )
    
    def __init__( self, path, log=None, port=None, init = False ):
        self.server = None
        self.siteName = None
        self.stylesheetPath = None
        self.flagCacheStylesheets = None
        self.authenticator = None
        self.baseUrl = None
        self.httpPort = port
        self.stylesheet = None

        self.logFile = None

        self.database = Database( wiki = self )
        if not self.database.connect( path, init ):
            raise DatabaseError( "Could not connect to database at '%s'" % (path,) )

        if log is None:
            log = self.database.getConfig( 'log-path' )
        
            if log is None:
                log = path + ".log"

        if isinstance( log, StringType ):
            try:
                self.logFile = open( log, "a" )
            except IOError, exc:
                self.logFile = sys.stderr
                self.logLine( 
                    "Could not access %s for logging. Using stderr.",
                    log
                )
        else:
            self.logFile = log

        self.lexicon = None
        self.gateway_interfaces = None
        self.method_interfaces = None
    
    def parseGid( self, nextGroup ):
        import grp

        try:
            return int( nextGroup )
        except ValueError, err:
            pass

        try:
            groupEntry = grp.getgrnam( nextGroup )

            return groupEntry[2]
        except KeyError, err:
            self.logLine( "Could not determine the group ID for group '%s'.",
                nextGroup
            )

        return None

    def parseUid( self, nextUser ):
        import pwd

        try:
            return int( nextUser )
        except ValueError, err:
            pass

        try:
            userEntry = pwd.getpwnam( nextUser )

            return userEntry[2]
        except KeyError, err:
            self.logLine( "Could not determine the user ID for user '%s'.",
                nextGroup
            )

        return None

    def genInterfaces( self ):
        if self.lexicon is None:
            self.lexicon, self.gateway_interfaces, self.method_interfaces = (
                collate_interfaces( self )
            )
        

    def runForever( self ):
        self.genInterfaces()

        server = self.getServer()

        nextGroup = self.getDatabase().getConfig( "set-gid", None )
        if nextGroup is not None:
            gid = self.parseGid( nextGroup )

            if gid is None: return

            try:
                os.setgid( gid )
            except OSError, exc:
                self.logLine(
                    "Could not change process group to %s -- try starting cloud-wiki as root.",
                    nextGroup
                )
                return
        
        nextUser = self.getDatabase().getConfig( "set-uid", None )
        if nextUser is not None:
            uid = self.parseUid( nextUser )
            if uid is None: return

            try:
                os.setuid( uid )
            except OSError, exc:
                self.logLine(
                    "Could not change process user to %s -- try starting cloud-wiki as root.",
                    nextUser
                )
                return
       
        server.runForever()

    def getServer( self ):
        if self.server is None: self.genServer()
        
        return self.server

    def usingCodex( self ):
        return self.server is not None
        
    def getDatabase( self ):
        return self.database
                
    def genServer( self ):    
        self.server = Server( wiki = self, port = self.getHttpPort() )
        
    def getStylesheetPath( self ):
        if self.stylesheetPath is None: self.genStylesheetPath()
        
        return self.stylesheetPath

    def genStylesheetPath( self ):
        db = self.getDatabase()
        stylesheetPath = db.getConfig( "stylesheet-path", 'style.css' )

        if os.path.isabs( stylesheetPath ):
            self.stylesheetPath = stylesheetPath
        else:
            self.stylesheetPath = os.path.join( 
                db.getDirectory(), stylesheetPath 
            )

    def shouldCacheStylesheets( self ):
        if self.flagCacheStylesheets is None: self.checkCacheStylesheets()
        return self.flagCacheStylesheets

    def checkCacheStylesheets( self ):
        self.flagCacheStylesheets = self.getDatabase().getConfig( 
            'cache-stylesheets', 'no'
        ).lower() in [
            'true', 't', 'yes', 'y'
        ]

    def getStylesheet( self ):
        if self.stylesheet is None:
            if self.shouldCacheStylesheets():
                self.stylesheet = "\n".join(
                    open( self.getStylesheetPath(), "r" ).readlines()
                )
            else:
                return "\n".join(
                    open( self.getStylesheetPath(), "r" ).readlines()
                )

        return self.stylesheet

    def getLogFile( self ):
        return self.logFile
        
    def logLine( self, message, *args ):
        self.logData( message + "\n", *args )

    def logData( self, message, *args ):
        lf = self.getLogFile()
        
        if lf is None: return

        if args:
            lf.write( message % args )
        else:
            lf.write( message )

    def getHttpPort( self ):
        if self.httpPort is None: self.genHttpPort()
        return self.httpPort
            
    def genHttpPort( self ):
        port = self.getDatabase().getConfig( 'http-port', None )
        
        if port is not None: 
            self.httpPort = int( port )
        else:
            self.httpPort = 8080

    def getSitename( self ):
        if self.siteName is None: self.genSitename()
        return self.siteName

    def genSitename( self ):
        self.siteName = self.getDatabase().getConfig( 
            "site-title", "AnonyWiki" 
        ) 
    
    def getBaseUrl( self ):
        if self.baseUrl is None:
            self.genBaseUrl()
        return self.baseUrl

    def genBaseUrl( self ):
        self.baseUrl = self.getDatabase().getConfig( "base-url", "" )

    def shouldMentionUsers( self ):
        return self.getAuthenticator().shouldMentionUsers()
    
    def getAuthenticator( self ):
        if self.authenticator is None:
            self.genAuthenticator( )

        return self.authenticator

    def genAuthenticator( self ):
        key = self.getDatabase().getConfig( 'site-auth' )
        scheme = authentication_schemes.get( key )

        if scheme is None:
            scheme = NoneAuthenticator

        self.authenticator = scheme( self )

    def getGatewayFor( self, key ):
        if self.gateway_interfaces is not None:
            return self.gateway_interfaces.get( key )
        else:
            self.lexicon, interface = load_gateway( self, key, self.lexicon )
            return interface
            
    def getMethodFor( self, key ):
        if self.method_interfaces is not None:
            return self.method_interfaces.get( key )
        else:
            self.lexicon, interface = load_method( self, key, self.lexicon )
            return interface

    def getLexicon( self ):
        return self.lexicon

    def getVersion( self ):
        return 2,1

    def authenticate( self, req, res ):
        "authenticates the user specified by the request, and may update the response with a session token;"
        " will assign the request's user attribute if authentication was successful."
        
        auth = self.getAuthenticator()
        
        if req.getAction() in ['logout', 'Logout']:
            res.addCookie( 'tk', None )
            req.setAction( '' )
            return
            
        tk = req.getCookie( 'tk', None )
        if tk is not None:
            un = auth.getUserForToken( tk )
            if un:
                req.setUser( un )
                return
        
        args = req.getArgs()

        un = args.get('un')        
        if un is None: return
            
        pw = args.get('pw')
        if pw is None: return
            
        results = auth.authenticate( un, pw )
        if results:
            un, tk = results
            res.addCookie( 'tk', tk )
            req.setUser( un )
                    
    def respondTo( self, req ):
        "invoked by a request when it has fully parsed the HTTP request"
        res = Response()
        
        try:
            self.authenticate( req, res )
        
            fg = self.getGatewayFor( req.getQuery() )
            if fg: 
                self.getLexicon().execFragment( 
                    fg, res.write, { 'req': req, 'res': res } 
                )
                return res
            
            fg = self.getMethodFor( req.getAction() )
            if fg:
                req.normalizeQuery()
                self.getLexicon().execFragment( 
                    fg, res.write, { 'req': req, 'res': res } 
                )
                return res

            raise InvalidRequestError( request=req.getAction() )
        except IHateFavicons, exc:
            res.setContent( exc.asHtml() )
            res.setCode( exc.httpCode )
            return res
        except Exception, exc:
            for line in format_exception( *sys.exc_info() ):
                self.logLine( line )

            try:
                res.setContent( exc.asHtml() )
                res.setCode( exc.httpCode )
            except:
                res.setCode( 500 )
                res.setContent( "<HTML><BODY>Error 500 -- Internal Server Error</BODY></HTML>" )
            return res

        
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.