mirror of https://github.com/tLDP/LDP
xsl DocBook stylesheets.
This commit is contained in:
parent
9293e7d8cd
commit
c3c1573efa
|
@ -1,14 +1,21 @@
|
|||
Copyright 2000, 2001, 2002 David C. Merrill <david@lupercalia.net>, Lead Developer
|
||||
Rick Welykochy <rick@praxis.com.au>, bugfixes for the original LDP Database
|
||||
The KDE Project http://www.kde.org, for icons
|
||||
Copyright 2002 Nicolas Chauvat <nicolas.chauvat@logilab.fr> for the Python port.
|
||||
Copyright 2002 Xavier Antoviaque for the Python port.
|
||||
David C. Merrill <david@lupercalia.net>, Lead Developer
|
||||
Copyright 2000, 2001, 2002 David C. Merrill
|
||||
Copyright 2002 Nicolas Chauvat <nicolas.chauvat@logilab.fr>
|
||||
Copyright 2002 Xavier Antoviaque
|
||||
|
||||
Work in progress :
|
||||
|
||||
I18N support and french localization :
|
||||
Thanks to:
|
||||
|
||||
Rick Welykochy <rick@praxis.com.au>, bugfixes for the original LDPDB
|
||||
|
||||
The KDE Project http://www.kde.org, for icons
|
||||
|
||||
|
||||
Current Maintainers:
|
||||
|
||||
I18N support and french localization:
|
||||
Nicolas Chauvat (started on 2002-05-24)
|
||||
|
||||
Mirroring and Document Conversion :
|
||||
Mirroring and Document Conversion:
|
||||
David Merrill
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ files.
|
|||
Files are installed into the following locations by default. To change
|
||||
them, edit the Makefiles.
|
||||
|
||||
binaries: /usr/local/bin
|
||||
man pages: /usr/share/man/man5
|
||||
/usr/share/man/man8
|
||||
binaries: /usr/local/bin
|
||||
man pages: /usr/share/man/man5
|
||||
/usr/share/man/man8
|
||||
Lampadas.pth: /usr/local/lib/site-python
|
||||
python modules: /usr/local/lib/site-python/Lampadas
|
||||
html, png, css: /usr/local/share/lampadas/www
|
||||
|
@ -23,9 +23,15 @@ PostgreSQL (I think 6.x is okay, but have not tested it).
|
|||
xsltproc for xml/xslt stylesheet processing
|
||||
wt2db 0.4 or later for WikiText conversions
|
||||
texi2db for Texinfo conversions
|
||||
xmllint for SGML to XML conversions
|
||||
jade or openjade for LinuxDoc conversions
|
||||
xmllint for SGML to XML conversions and validation
|
||||
docbook-to-man for manpage generation
|
||||
docbook dtds
|
||||
docbook xsl stylesheets from Norm Walsh
|
||||
docbook dsssl stylesheets
|
||||
linuxdoc dtds
|
||||
linuxdoc dsssl stylesheets
|
||||
tar for .tar and .tar.gz archive support
|
||||
gunzip for .gz archive support
|
||||
make for publishing static content
|
||||
lynx for text output support
|
||||
|
|
|
@ -2,7 +2,7 @@ logprefix = /var/log
|
|||
|
||||
INSTALLDIR = install -d
|
||||
|
||||
all: bin pylib database www conf docs
|
||||
all: bin pylib database www conf docs xsl
|
||||
|
||||
install: bin pylib www conf docs
|
||||
$(INSTALLDIR) $(logprefix)/lampadas
|
||||
|
@ -12,6 +12,7 @@ install: bin pylib www conf docs
|
|||
cd www; $(MAKE) install
|
||||
cd conf; $(MAKE) install
|
||||
cd doc; $(MAKE) install
|
||||
cd xsl; $(MAKE) install
|
||||
echo "Lampadas installation complete."
|
||||
|
||||
clean:
|
||||
|
@ -21,6 +22,7 @@ clean:
|
|||
cd www; $(MAKE) clean
|
||||
cd conf; $(MAKE) clean
|
||||
cd doc; $(MAKE) clean
|
||||
cd xsl; $(MAKE) clean
|
||||
|
||||
bin:
|
||||
cd bin; $(MAKE) all
|
||||
|
@ -40,3 +42,6 @@ conf:
|
|||
docs:
|
||||
cd doc; $(MAKE) all
|
||||
|
||||
xsl:
|
||||
cd xsl; $(MAKE) all
|
||||
|
||||
|
|
|
@ -5,10 +5,6 @@ Lampadas is a young project, although it is based on the LDP Database,
|
|||
which has been in actual use for over a year. It is not yet recommended
|
||||
for production use.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
See INSTALL for requirements.
|
||||
|
||||
|
||||
|
@ -17,25 +13,32 @@ Applicable Standards
|
|||
|
||||
Lampadas adheres to the following standards:
|
||||
|
||||
ISO 8879, Standard Generalized Markup Language
|
||||
XML?
|
||||
HTML?
|
||||
CSS?
|
||||
XSLT?
|
||||
ISO 639 Language Codes, http://www.w3.org/WAI/ER/IG/ert/iso639.htm
|
||||
Unicode Encoding, http://www.unicode.org/unicode/standard/standard.html
|
||||
DocBook XML DTD
|
||||
OMF XML DTD
|
||||
|
||||
|
||||
Security
|
||||
--------
|
||||
|
||||
Anyone may browse and search the database, however only registered users can
|
||||
make changes to the database at this time.
|
||||
make changes to the database.
|
||||
|
||||
Each user is recorded in the `username' table. If the 'admin' field is 't',
|
||||
the user may alter any document information in the database. If the 'sysadmin'
|
||||
field is set to 't', the user may also alter system data, such as
|
||||
configuration records. If the document_user table has a record for a user,
|
||||
the user may edit those documents and their meta-data.
|
||||
the user may edit any assigned documents and their meta-data.
|
||||
|
||||
Admins may add new maintainers and documents.
|
||||
|
||||
Only admins and authors may edit documents, and authors may only edit their
|
||||
Only admins and authors may edit documents, but authors may only edit their
|
||||
own documents.
|
||||
|
||||
The SysAdmin level allows very low level system configuration. I recommend
|
||||
|
|
|
@ -17,11 +17,12 @@ just be a call to that library. So put the Python module in pylib, but put the
|
|||
wrapper script under /lampadas/cron (a new directory). See the old Perl code,
|
||||
and just port it. Feel free to recommend additional metrics that would be
|
||||
valuable to the management of the site. Also add user count, which didn't
|
||||
apply to the LDPL but does apply to Lampadas. And docs served, pages served.
|
||||
apply to the LDPDB but does apply to Lampadas. And docs served, pages served.
|
||||
|
||||
Write a Makefile to install Lampadas onto a fresh system. Also let `make test`
|
||||
run the unit tests, and `make clean` remove any installation. `make tar` and
|
||||
other build targets would be nice, too.
|
||||
-- wrote Makefiles, but no test target yet
|
||||
|
||||
Add date_entered timestamps to additional records where it is appropriate.
|
||||
Maybe even to all of them. It's nice meta-data to have. And add creator_id
|
||||
|
@ -74,6 +75,7 @@ high priority because it will give us a huge amount of visibility and help
|
|||
build the project.
|
||||
|
||||
Write manpage.
|
||||
|
||||
-- done, for lampadasdb and lampadasweb
|
||||
|
||||
Need mod_perl front end.
|
||||
|
||||
|
|
|
@ -9,128 +9,130 @@ import StringIO
|
|||
import shutil
|
||||
import StringIO
|
||||
|
||||
import BaseHTTPServer
|
||||
import CGIHTTPServer
|
||||
|
||||
from Log import Log
|
||||
from Config import config
|
||||
from Log import log
|
||||
from HTML import PageFactory
|
||||
from Globals import VERSION
|
||||
import Config
|
||||
from URLParse import URI
|
||||
|
||||
Log = Log()
|
||||
Config = Config.Config()
|
||||
P = PageFactory()
|
||||
|
||||
BaseClass = BaseHTTPServer.BaseHTTPRequestHandler
|
||||
#BaseClass = BaseHTTPServer.BaseHTTPRequestHandler
|
||||
BaseClass = CGIHTTPServer.CGIHTTPRequestHandler
|
||||
|
||||
class RequestHandler(BaseClass):
|
||||
"""
|
||||
Intercepts the HTTP requests and serves them.
|
||||
"""
|
||||
def do_GET(self):
|
||||
fd = self.send_head()
|
||||
if fd:
|
||||
shutil.copyfileobj(fd, self.wfile)
|
||||
fd.close
|
||||
|
||||
def do_HEAD(self):
|
||||
fd = self.send_head()
|
||||
fd.close()
|
||||
|
||||
def send_head(self):
|
||||
"""
|
||||
Send the requested page.
|
||||
"""
|
||||
uri = URI(self.path)
|
||||
filename = Config.FileDir + uri.Path + uri.Filename
|
||||
filename = filename.replace('//','/')
|
||||
Log.Write(3, 'looking for file ' + filename)
|
||||
|
||||
if os.path.isfile(filename):
|
||||
return self.send_File(filename)
|
||||
"""
|
||||
Intercepts the HTTP requests and serves them.
|
||||
"""
|
||||
def do_GET(self):
|
||||
fd = self.send_head()
|
||||
if fd:
|
||||
shutil.copyfileobj(fd, self.wfile)
|
||||
fd.close
|
||||
|
||||
def do_HEAD(self):
|
||||
fd = self.send_head()
|
||||
fd.close()
|
||||
|
||||
def send_head(self):
|
||||
"""
|
||||
Send the requested page
|
||||
"""
|
||||
uri = URI(self.path)
|
||||
print uri.Path
|
||||
print uri.Filename
|
||||
filename = config.file_dir + uri.path + '/' + uri.filename
|
||||
filename = filename.replace('//','/')
|
||||
Log.Write(3, 'looking for file ' + filename)
|
||||
|
||||
if os.path.isfile(filename):
|
||||
return self.send_File(filename)
|
||||
|
||||
Log.Write(3, 'Sending dynamic page')
|
||||
return self.send_HTML(P.Page(self.path, 'EN'))
|
||||
Log.Write(3, 'Sending dynamic page')
|
||||
return self.send_HTML(P.Page(self.path))
|
||||
|
||||
def send_HTML(self, HTML):
|
||||
"""
|
||||
Send the passed HTML page.
|
||||
"""
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.send_header("Content-length", len(HTML))
|
||||
self.end_headers()
|
||||
return StringIO.StringIO(HTML)
|
||||
|
||||
def send_File(self, filename):
|
||||
"""
|
||||
Send the requested file.
|
||||
"""
|
||||
Log.Write(3, 'Sending file ' + filename)
|
||||
temp = string.split(filename, ".")
|
||||
if len(temp) > 1:
|
||||
fileext = temp[1]
|
||||
else:
|
||||
if os.path.isfile(filename + ".png"):
|
||||
fileext = "png"
|
||||
elif os.path.isfile(filename + ".jpeg"):
|
||||
fileext = "jpeg"
|
||||
if os.path.isfile(filename + ".jpg"):
|
||||
fileext = "jpg"
|
||||
if os.path.isfile(filename + ".gif"):
|
||||
fileext = "gif"
|
||||
if fileext:
|
||||
filename += "." + fileext
|
||||
def send_HTML(self, HTML):
|
||||
"""
|
||||
Send the passed HTML page.
|
||||
"""
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.send_header("Content-length", len(HTML))
|
||||
self.end_headers()
|
||||
return StringIO.StringIO(HTML)
|
||||
|
||||
def send_File(self, filename):
|
||||
"""
|
||||
Send the requested file.
|
||||
"""
|
||||
Log.Write(3, 'Sending file ' + filename)
|
||||
temp = string.split(filename, ".")
|
||||
if len(temp) > 1:
|
||||
fileext = temp[1]
|
||||
else:
|
||||
if os.path.isfile(filename + ".png"):
|
||||
fileext = "png"
|
||||
elif os.path.isfile(filename + ".jpeg"):
|
||||
fileext = "jpeg"
|
||||
if os.path.isfile(filename + ".jpg"):
|
||||
fileext = "jpg"
|
||||
if os.path.isfile(filename + ".gif"):
|
||||
fileext = "gif"
|
||||
if fileext:
|
||||
filename += "." + fileext
|
||||
|
||||
# Determine mimetype from extension
|
||||
if fileext == "html" or fileext == "htm":
|
||||
mimetype = "text/html"
|
||||
elif fileext == "png":
|
||||
mimetype = "image/png"
|
||||
elif fileext == "gif":
|
||||
mimetype = "image/gif"
|
||||
elif fileext == "jpg" or fileext == "jpeg":
|
||||
mimetype = "image/jpeg"
|
||||
elif fileext == "css":
|
||||
mimetype = "text/css"
|
||||
else:
|
||||
mimetype = "text/plain"
|
||||
# Determine mimetype from extension
|
||||
if fileext == "html" or fileext == "htm":
|
||||
mimetype = "text/html"
|
||||
elif fileext == "png":
|
||||
mimetype = "image/png"
|
||||
elif fileext == "gif":
|
||||
mimetype = "image/gif"
|
||||
elif fileext == "jpg" or fileext == "jpeg":
|
||||
mimetype = "image/jpeg"
|
||||
elif fileext == "css":
|
||||
mimetype = "text/css"
|
||||
else:
|
||||
mimetype = "text/plain"
|
||||
|
||||
fd = open(filename, 'r')
|
||||
filesize = os.fstat(fd.fileno())[stat.ST_SIZE]
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", mimetype)
|
||||
self.send_header("Content-length", filesize)
|
||||
self.end_headers()
|
||||
return fd
|
||||
fd = open(filename, 'r')
|
||||
filesize = os.fstat(fd.fileno())[stat.ST_SIZE]
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", mimetype)
|
||||
self.send_header("Content-length", filesize)
|
||||
self.end_headers()
|
||||
return fd
|
||||
|
||||
def send_Text(self, text):
|
||||
"""
|
||||
Send a text message.
|
||||
"""
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/plain")
|
||||
self.send_header("Content-length", len(text))
|
||||
self.end_headers()
|
||||
return StringIO.StringIO(text)
|
||||
def send_Text(self, text):
|
||||
"""
|
||||
Send a text message.
|
||||
"""
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/plain")
|
||||
self.send_header("Content-length", len(text))
|
||||
self.end_headers()
|
||||
return StringIO.StringIO(text)
|
||||
|
||||
|
||||
def WebServer():
|
||||
"""
|
||||
Initialize the server.
|
||||
"""
|
||||
interface = Config.Interface
|
||||
port = Config.Port
|
||||
"""
|
||||
Initialize the server.
|
||||
"""
|
||||
interface = config.interface
|
||||
port = config.port
|
||||
|
||||
print "Lampadas " + VERSION + " -- development version!"
|
||||
if interface != '':
|
||||
print '(Listening on interface %s, port %s)' % (interface, port)
|
||||
else:
|
||||
print '(Listening on all interfaces, port %s)' % port
|
||||
server = BaseHTTPServer.HTTPServer((interface, port), RequestHandler)
|
||||
server.serve_forever()
|
||||
print "Lampadas " + VERSION + " -- development version!"
|
||||
if interface != '':
|
||||
print '(Listening on interface %s, port %s)' % (interface, port)
|
||||
else:
|
||||
print '(Listening on all interfaces, port %s)' % port
|
||||
# server = BaseHTTPServer.HTTPServer((interface, port), RequestHandler)
|
||||
server = CGIHTTPServer.BaseHTTPServer.HTTPServer((interface, port), RequestHandler)
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
WebServer()
|
||||
WebServer()
|
||||
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
These base classes are used to build other Lampadas objects upon.
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Configuration module
|
||||
|
||||
|
@ -11,81 +29,91 @@ This module provides configuration information from lampadas.conf.
|
|||
|
||||
# Globals
|
||||
|
||||
CONF_FILE = '/etc/lampadas.conf'
|
||||
|
||||
CONF_FILE = '/etc/lampadas/lampadas.conf'
|
||||
|
||||
# BaseConfig ###############################################################
|
||||
|
||||
class ConfigFileReadErrorException(Exception) :
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
class Config:
|
||||
"""
|
||||
Basic configuration options (dbname, dbtype), used to know where we can find
|
||||
the database.
|
||||
"""
|
||||
"""
|
||||
Basic configuration options (dbname, dbtype), used to know where we can find
|
||||
the database.
|
||||
"""
|
||||
|
||||
DBType = ''
|
||||
DBName = ''
|
||||
LogFile = ''
|
||||
LogLevel = 0
|
||||
LogSQL = ''
|
||||
LogConsole = 0
|
||||
Interface = ''
|
||||
Port = 80
|
||||
Hostname = ''
|
||||
RootDir = ''
|
||||
FileDir = ''
|
||||
CVSRoot = ''
|
||||
CacheDir = ''
|
||||
db_type = ''
|
||||
db_name = ''
|
||||
log_file = ''
|
||||
log_level = 0
|
||||
log_sql = ''
|
||||
log_console = 0
|
||||
interface = ''
|
||||
port = 80
|
||||
hostname = ''
|
||||
root_dir = ''
|
||||
file_dir = ''
|
||||
cvs_root = ''
|
||||
cache_dir = ''
|
||||
xslt_html = ''
|
||||
xslt_chunk = ''
|
||||
xslt_print = ''
|
||||
|
||||
def __init__(self) :
|
||||
import ConfigParser
|
||||
def __init__(self) :
|
||||
import ConfigParser
|
||||
|
||||
self.config = ConfigParser.ConfigParser()
|
||||
self.config.readfp(open(CONF_FILE))
|
||||
self.config = ConfigParser.ConfigParser()
|
||||
self.config.readfp(open(CONF_FILE))
|
||||
|
||||
self.DBType = self.ReadVar('DB', 'dbtype')
|
||||
self.DBName = self.ReadVar('DB', 'dbname')
|
||||
self.LogFile = self.ReadVar('LOG', 'logfile')
|
||||
self.LogLevel = int(self.ReadVar('LOG', 'loglevel'))
|
||||
self.LogSQL = int(self.ReadVar('LOG', 'logsql'))
|
||||
self.LogConsole = int(self.ReadVar('LOG', 'logcon'))
|
||||
self.Interface = self.ReadVar('WEBSERVER', 'interface')
|
||||
self.Port = int(self.ReadVar('WEBSERVER', 'port'))
|
||||
self.Hostname = self.ReadVar('WEBSERVER', 'hostname')
|
||||
self.RootDir = self.ReadVar('WEBSERVER', 'rootdir')
|
||||
self.FileDir = self.ReadVar('WEBSERVER', 'filedir')
|
||||
self.CVSRoot = self.ReadVar('CVS', 'cvsroot')
|
||||
self.cache_dir = self.ReadVar('MIRROR', 'cachedir')
|
||||
self.db_type = self.read_var('DB', 'dbtype')
|
||||
self.db_name = self.read_var('DB', 'dbname')
|
||||
self.log_file = self.read_var('LOG', 'logfile')
|
||||
self.log_level = int(self.read_var('LOG', 'loglevel'))
|
||||
self.log_sql = int(self.read_var('LOG', 'logsql'))
|
||||
self.log_console = int(self.read_var('LOG', 'logcon'))
|
||||
self.interface = self.read_var('WEBSERVER', 'interface')
|
||||
self.port = int(self.read_var('WEBSERVER', 'port'))
|
||||
self.hostname = self.read_var('WEBSERVER', 'hostname')
|
||||
self.root_dir = self.read_var('WEBSERVER', 'rootdir')
|
||||
self.file_dir = self.read_var('WEBSERVER', 'filedir')
|
||||
self.cvs_root = self.read_var('CVS', 'cvsroot')
|
||||
self.cache_dir = self.read_var('MIRROR', 'cachedir')
|
||||
self.xslt_html = self.read_var('XSLT', 'xslt_html')
|
||||
self.xslt_chunk = self.read_var('XSLT', 'xslt_chunk')
|
||||
self.xslt_print = self.read_var('XSLT', 'xslt_print')
|
||||
|
||||
def ReadVar(self, section, name):
|
||||
if not self.config.has_section(section) :
|
||||
raise ConfigFileReadErrorException("File '" + CONF_FILE + "' is missing or does not contain a '" + section + "' section")
|
||||
def read_var(self, section, name):
|
||||
if not self.config.has_section(section) :
|
||||
raise ConfigFileReadErrorException("File '" + CONF_FILE + "' is missing or does not contain a '" + section + "' section")
|
||||
|
||||
if not self.config.has_option(section, name):
|
||||
raise ConfigFileReadErrorException("Can't read option '" + name + "' from " + CONF_FILE)
|
||||
if not self.config.has_option(section, name):
|
||||
raise ConfigFileReadErrorException("Can't read option '" + name + "' from " + CONF_FILE)
|
||||
|
||||
return self.config.get(section, name)
|
||||
|
||||
|
||||
return self.config.get(section, name)
|
||||
|
||||
## exports ##
|
||||
|
||||
config = Config()
|
||||
|
||||
# main
|
||||
if __name__ == '__main__' :
|
||||
print "Running unit tests..."
|
||||
Config = Config()
|
||||
assert Config.DBType > ''
|
||||
print "DBType= " + Config.DBType
|
||||
assert Config.DBName > ''
|
||||
print "DBName= " + Config.DBName
|
||||
assert Config.LogFile > ''
|
||||
print "LogFile=" + Config.LogFile
|
||||
print "LogSQL=" + str(Config.LogSQL)
|
||||
print "LogConsole=" + str(Config.LogConsole)
|
||||
print "Interface=" + Config.Interface
|
||||
print "Port=" + str(Config.Port)
|
||||
print "Hostname=" + Config.Hostname
|
||||
print "RootDir=" + Config.RootDir
|
||||
print "CVSRoot=" + Config.CVSRoot
|
||||
print "FileDir=" + Config.FileDir
|
||||
print "cache_dir=" + Config.cache_dir
|
||||
print "Unit tests complete."
|
||||
print "Running unit tests..."
|
||||
assert config.db_type > ''
|
||||
print "db_type= " + config.db_type
|
||||
assert config.db_name > ''
|
||||
print "db_name= " + config.db_name
|
||||
assert config.log_file > ''
|
||||
print "log_file=" + config.log_file
|
||||
print "log-sql=" + str(config.log_sql)
|
||||
print "log_console=" + str(config.log_console)
|
||||
print "interface=" + config.interface
|
||||
print "port=" + str(config.port)
|
||||
print "hostname=" + config.hostname
|
||||
print "root_dir=" + config.root_dir
|
||||
print "cvs_root=" + config.cvs_root
|
||||
print "file_dir=" + config.file_dir
|
||||
print "cache_dir=" + config.cache_dir
|
||||
print "xslt_html=" + config.xslt_html
|
||||
print "xslt_chunk=" + config.xslt_chunk
|
||||
print "xslt_print=" + config.xslt_print
|
||||
print "Unit tests complete."
|
||||
|
|
|
@ -1,8 +1,30 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Conversion Module
|
||||
|
||||
NOTE: This module is obsolete. When I realized every conversion
|
||||
was a call to an external program, I began writing a Makefile for
|
||||
each document during the mirroring process.
|
||||
|
||||
This module converts source documents into DocBook XML format.
|
||||
|
||||
Currently supported source formats are:
|
||||
|
@ -11,11 +33,15 @@ Currently supported source formats are:
|
|||
WikiText
|
||||
Texinfo
|
||||
DocBook SGML
|
||||
Linuxdoc
|
||||
|
||||
Working on:
|
||||
|
||||
Linuxdoc
|
||||
Pie-in-the-sky:
|
||||
|
||||
DebianDoc
|
||||
PyDoc
|
||||
*roff
|
||||
"""
|
||||
|
||||
# Modules ##################################################################
|
||||
|
@ -38,7 +64,7 @@ class Converter:
|
|||
|
||||
def text(self, Filename, Format):
|
||||
Log(3, 'Converting ' + Filename + ' from text')
|
||||
return WikiText(Filename)
|
||||
return wikitext(Filename)
|
||||
|
||||
def wikitext(self, Filename):
|
||||
Log(3, 'Converting ' + Filename + ' from WikiText')
|
||||
|
@ -52,32 +78,25 @@ class Converter:
|
|||
result = commands.getoutput(command)
|
||||
return result
|
||||
|
||||
def dbsgml(self, Filename):
|
||||
Log(3, 'Converting ' + Filename + ' from DocBook SGML')
|
||||
command = 'xmllint --sgml ' + Filename
|
||||
result = commands.getoutput(command)
|
||||
return result
|
||||
|
||||
def ldsgml(self, Filename):
|
||||
Log(3, 'Converting ' + Filename + ' from LinuxDoc SGML')
|
||||
command = ''
|
||||
result = commands.getoutput(command)
|
||||
return result
|
||||
|
||||
|
||||
def xml(self, Filename):
|
||||
command = 'xsltproc /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/docbook.xsl ' + Filename
|
||||
result = commands.getoutput(command)
|
||||
return result
|
||||
|
||||
def sgml(self, Filename, Format):
|
||||
command = 'xsltproc --docbook /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/docbook.xsl ' + Filename
|
||||
def dbsgml(self, Filename):
|
||||
Log(3, 'Converting ' + Filename + ' from DocBook SGML')
|
||||
command = 'xmllint --sgml ' + Filename
|
||||
result = commands.getoutput(command)
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
def main():
|
||||
|
||||
C = Converter()
|
||||
# output = C.texinfo('test/texinfo/texinfo.txi')
|
||||
output = C.dbsgml('test/db3.0sgml/RPM-HOWTO.sgml')
|
||||
print output
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Object Hierarchy Module
|
||||
|
||||
|
@ -15,18 +33,14 @@ performed through this layer.
|
|||
|
||||
from Globals import *
|
||||
from BaseClasses import *
|
||||
import Config
|
||||
import Database
|
||||
import Log
|
||||
from Config import config
|
||||
from Database import db
|
||||
from Log import log
|
||||
|
||||
|
||||
# Globals
|
||||
|
||||
Config = Config.Config()
|
||||
DB = Database.Database()
|
||||
DB.Connect(Config.DBType, Config.DBName)
|
||||
Log = Log.Log()
|
||||
|
||||
db.connect(config.db_type, config.db_name)
|
||||
|
||||
# Lampadas
|
||||
|
||||
|
@ -42,19 +56,18 @@ class Lampadas:
|
|||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.Log = Log
|
||||
self.Classes = Classes()
|
||||
self.Classes = Classes()
|
||||
self.Classes.Load()
|
||||
self.Config = Cfg()
|
||||
self.Docs = Docs()
|
||||
self.Config = Cfg()
|
||||
self.Docs = Docs()
|
||||
self.Docs.Load()
|
||||
self.DTDs = DTDs()
|
||||
self.Formats = Formats()
|
||||
self.Languages = Languages()
|
||||
self.PubStatuses = PubStatuses()
|
||||
self.ReviewStatuses = ReviewStatuses()
|
||||
self.Topics = Topics()
|
||||
self.Users = Users()
|
||||
self.DTDs = DTDs()
|
||||
self.Formats = Formats()
|
||||
self.Languages = Languages()
|
||||
self.PubStatuses = PubStatuses()
|
||||
self.ReviewStatuses = ReviewStatuses()
|
||||
self.Topics = Topics()
|
||||
self.Users = Users()
|
||||
|
||||
def User(self, UserID):
|
||||
return User(UserID)
|
||||
|
@ -72,7 +85,7 @@ class Classes(LampadasCollection):
|
|||
|
||||
def Load(self):
|
||||
self.sql = "SELECT class_id FROM class"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -94,7 +107,7 @@ class Class:
|
|||
def Load(self, row):
|
||||
self.ID = row[0]
|
||||
self.sql = "SELECT lang, class_name, class_description FROM class_i18n WHERE class_id=" + str(self.ID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -129,7 +142,7 @@ class Cfg(LampadasCollection):
|
|||
|
||||
def Load(self):
|
||||
self.sql = "SELECT name, value FROM config"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -145,81 +158,82 @@ class Docs(LampadasCollection):
|
|||
|
||||
def Load(self):
|
||||
self.sql = "SELECT doc_id, title, class_id, format_id, dtd, dtd_version, version, last_update, url, isbn, pub_status, review_status, tickle_date, pub_date, ref_url, tech_review_status, maintained, license, abstract, rating, lang, sk_seriesid FROM document"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
Log(3, 'Loading document')
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
newDoc = Doc()
|
||||
newDoc.Load(self.row)
|
||||
newDoc.LoadRow(self.row)
|
||||
self[newDoc.ID] = newDoc
|
||||
Log(3, 'Loaded document ' + str(newDoc.ID))
|
||||
|
||||
# FIXME: try instantiating a new document, then adding *it* to the collection,
|
||||
# rather than passing in all these parameters.
|
||||
|
||||
def Add(self, Title, ClassID, FormatID, DTD, DTDVersion, Version, LastUpdate, URL, ISBN, PubStatusCode, ReviewStatus, TickleDate, PubDate, HomeURL, TechReviewStatus, License, Abstract, Lang, SeriesID):
|
||||
self.id = DB.Value('SELECT max(doc_id) from document') + 1
|
||||
self.id = db.value('SELECT max(doc_id) from document') + 1
|
||||
self.sql = "INSERT INTO document(doc_id, title, class_id, format_id, dtd, dtd_version, version, last_update, url, isbn, pub_status, review_status, tickle_date, pub_date, ref_url, tech_review_status, license, abstract, lang, sk_seriesid) VALUES (" + str(self.id) + ", " + wsq(Title) + ", " + str(ClassID) + ", " + dbint(FormatID) + ", " + wsq(DTD) + ", " + wsq(DTDVersion) + ", " + wsq(Version) + ", " + wsq(LastUpdate) + ", " + wsq(URL) + ", " + wsq(ISBN) + ", " + wsq(PubStatusCode) + ", " + wsq(ReviewStatus) + ", " + wsq(TickleDate) + ", " + wsq(PubDate) + ", " + wsq(HomeURL) + ", " + wsq(TechReviewStatus) + ", " + wsq(License) + ", " + wsq(Abstract) + ", " + wsq(Lang) + ", " + wsq(SeriesID) + ")"
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
self.NewID = DB.Value('SELECT MAX(doc_id) from document')
|
||||
assert db.run_sql(self.sql) == 1
|
||||
db.commit()
|
||||
self.NewID = db.value('SELECT MAX(doc_id) from document')
|
||||
newDoc = Doc(self.NewID)
|
||||
self[self.NewID] = newDoc
|
||||
return self.NewID
|
||||
|
||||
def Del(self, id):
|
||||
self.sql = ('DELETE from document WHERE doc_id=' + str(id))
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
assert db.runsql(self.sql) == 1
|
||||
db.commit()
|
||||
del self[id]
|
||||
|
||||
class Doc:
|
||||
"""
|
||||
A document in any format, whether local or remote.
|
||||
"""
|
||||
"""
|
||||
A document in any format, whether local or remote.
|
||||
"""
|
||||
|
||||
def __init__(self, id=None):
|
||||
if id == None: return
|
||||
self.sql = "SELECT doc_id, title, class_id, format_id, dtd, dtd_version, version, last_update, url, isbn, pub_status, review_status, tickle_date, pub_date, ref_url, tech_review_status, maintained, license, abstract, rating, lang, sk_seriesid FROM document WHERE doc_id=" + str(id)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.row = self.cursor.fetchone()
|
||||
self.Load(self.row)
|
||||
def __init__(self, id=None):
|
||||
if id == None: return
|
||||
self.Load(id)
|
||||
|
||||
def Load(self, row):
|
||||
self.ID = row[0]
|
||||
self.Title = trim(row[1])
|
||||
self.ClassID = row[2]
|
||||
self.FormatID = row[3]
|
||||
self.DTD = trim(row[4])
|
||||
self.DTDVersion = trim(row[5])
|
||||
self.Version = trim(row[6])
|
||||
self.LastUpdate = trim(row[7])
|
||||
self.URL = trim(row[8])
|
||||
self.ISBN = trim(row[9])
|
||||
self.PubStatusCode = trim(row[10])
|
||||
self.ReviewStatus = trim(row[11])
|
||||
self.TickleDate = trim(row[12])
|
||||
self.PubDate = trim(row[13])
|
||||
self.HomeURL = trim(row[14])
|
||||
self.TechReviewStatus = trim(row[15])
|
||||
self.Maintained = tf2bool(row[16])
|
||||
self.License = trim(row[17])
|
||||
self.Abstract = trim(row[18])
|
||||
self.Rating = safeint(row[19])
|
||||
self.Lang = trim(row[20])
|
||||
self.SeriesID = trim(row[21])
|
||||
def Load(self, id):
|
||||
sql = "SELECT doc_id, title, class_id, format_id, dtd, dtd_version, version, last_update, url, isbn, pub_status, review_status, tickle_date, pub_date, ref_url, tech_review_status, maintained, license, abstract, rating, lang, sk_seriesid FROM document WHERE doc_id=" + str(id)
|
||||
cursor = db.select(sql)
|
||||
row = cursor.fetchone()
|
||||
self.LoadRow(row)
|
||||
|
||||
self.Errs = DocErrs(self.ID)
|
||||
self.Files = DocFiles(self.ID)
|
||||
self.Ratings = DocRatings(self.ID)
|
||||
self.Ratings.Parent = self
|
||||
self.Versions = DocVersions(self.ID)
|
||||
def LoadRow(self, row):
|
||||
self.ID = row[0]
|
||||
self.Title = trim(row[1])
|
||||
self.ClassID = row[2]
|
||||
self.FormatID = row[3]
|
||||
self.DTD = trim(row[4])
|
||||
self.DTDVersion = trim(row[5])
|
||||
self.Version = trim(row[6])
|
||||
self.LastUpdate = trim(row[7])
|
||||
self.URL = trim(row[8])
|
||||
self.ISBN = trim(row[9])
|
||||
self.PubStatusCode = trim(row[10])
|
||||
self.ReviewStatus = trim(row[11])
|
||||
self.TickleDate = trim(row[12])
|
||||
self.PubDate = trim(row[13])
|
||||
self.HomeURL = trim(row[14])
|
||||
self.TechReviewStatus = trim(row[15])
|
||||
self.Maintained = tf2bool(row[16])
|
||||
self.License = trim(row[17])
|
||||
self.Abstract = trim(row[18])
|
||||
self.Rating = safeint(row[19])
|
||||
self.Lang = trim(row[20])
|
||||
self.SeriesID = trim(row[21])
|
||||
|
||||
def Save(self):
|
||||
self.sql = "UPDATE document SET title=" + wsq(self.Title) + ", class_id=" + str(self.ClassID) + ", format_id=" + dbint(self.FormatID) + ", dtd=" + wsq(self.DTD) + ", dtd_version=" + wsq(self.DTDVersion) + ", version=" + wsq(self.Version) + ", last_update=" + wsq(self.LastUpdate) + ", url=" + wsq(self.URL) + ", isbn=" + wsq(self.ISBN) + ", pub_status=" + wsq(self.PubStatusCode) + ", review_status=" + wsq(self.ReviewStatus) + ", tickle_date=" + wsq(self.TickleDate) + ", pub_date=" + wsq(self.PubDate) + ", ref_url=" + wsq(self.HomeURL) + ", tech_review_status=" + wsq(self.TechReviewStatus) + ", maintained=" + wsq(bool2tf(self.Maintained)) + ", license=" + wsq(self.License) + ", abstract=" + wsq(self.Abstract) + ", rating=" + dbint(self.Rating) + ", lang=" + wsq(self.Lang) + ", sk_seriesid=" + wsq(self.SeriesID) + " WHERE doc_id=" + str(self.ID)
|
||||
DB.Exec(self.sql)
|
||||
DB.Commit()
|
||||
self.Errs = DocErrs(self.ID)
|
||||
self.Files = DocFiles(self.ID)
|
||||
self.Ratings = DocRatings(self.ID)
|
||||
self.Ratings.Parent = self
|
||||
self.Versions = DocVersions(self.ID)
|
||||
|
||||
def Save(self):
|
||||
self.sql = "UPDATE document SET title=" + wsq(self.Title) + ", class_id=" + str(self.ClassID) + ", format_id=" + dbint(self.FormatID) + ", dtd=" + wsq(self.DTD) + ", dtd_version=" + wsq(self.DTDVersion) + ", version=" + wsq(self.Version) + ", last_update=" + wsq(self.LastUpdate) + ", url=" + wsq(self.URL) + ", isbn=" + wsq(self.ISBN) + ", pub_status=" + wsq(self.PubStatusCode) + ", review_status=" + wsq(self.ReviewStatus) + ", tickle_date=" + wsq(self.TickleDate) + ", pub_date=" + wsq(self.PubDate) + ", ref_url=" + wsq(self.HomeURL) + ", tech_review_status=" + wsq(self.TechReviewStatus) + ", maintained=" + wsq(bool2tf(self.Maintained)) + ", license=" + wsq(self.License) + ", abstract=" + wsq(self.Abstract) + ", rating=" + dbint(self.Rating) + ", lang=" + wsq(self.Lang) + ", sk_seriesid=" + wsq(self.SeriesID) + " WHERE doc_id=" + str(self.ID)
|
||||
db.runsql(self.sql)
|
||||
db.commit()
|
||||
|
||||
|
||||
# DocErrs
|
||||
|
@ -234,7 +248,7 @@ class DocErrs(LampadasList):
|
|||
assert not DocID == None
|
||||
self.DocID = DocID
|
||||
self.sql = "SELECT err_id FROM document_error WHERE doc_id=" + str(DocID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -244,8 +258,8 @@ class DocErrs(LampadasList):
|
|||
|
||||
def Clear(self):
|
||||
self.sql = "DELETE FROM document_error WHERE doc_id=" + str(self.DocID)
|
||||
DB.Exec(self.sql)
|
||||
DB.Commit()
|
||||
db.runsql(self.sql)
|
||||
db.commit()
|
||||
self.list = []
|
||||
|
||||
# FIXME: Try instantiating a DocErr object, then adding it to the *document*
|
||||
|
@ -253,12 +267,12 @@ class DocErrs(LampadasList):
|
|||
|
||||
def Add(self, ErrID):
|
||||
self.sql = "INSERT INTO document_error(doc_id, err_id) VALUES (" + str(self.DocID) + ", " + wsq(ErrID)
|
||||
assert DB.Exec(self.sql) == 1
|
||||
assert db.runsql(self.sql) == 1
|
||||
newDocErr = DocErr()
|
||||
newDocErr.DocID = self.DocID
|
||||
newDocErr.ErrID = ErrID
|
||||
self.list = self.list + [newDocErr]
|
||||
DB.Commit()
|
||||
db.commit()
|
||||
|
||||
class DocErr:
|
||||
"""
|
||||
|
@ -284,7 +298,7 @@ class DocFiles(LampadasCollection):
|
|||
assert not DocID == None
|
||||
self.DocID = DocID
|
||||
self.sql = "SELECT filename, format_id FROM document_file WHERE doc_id=" + str(DocID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -294,8 +308,8 @@ class DocFiles(LampadasCollection):
|
|||
|
||||
def Add(self, DocID, Filename, FormatID=None):
|
||||
self.sql = 'INSERT INTO document_file (doc_id, filename, format_id) VALUES (' + str(DocID) + ', ' + wsq(Filename) + ', ' + dbint(FormatID) + ')'
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
assert db.runsql(self.sql) == 1
|
||||
db.commit()
|
||||
newDocFile = DocFile()
|
||||
newDocFile.DocID = DocID
|
||||
newDocFile.Filename = Filename
|
||||
|
@ -303,8 +317,8 @@ class DocFiles(LampadasCollection):
|
|||
|
||||
def Clear(self):
|
||||
self.sql = "DELETE FROM document_file WHERE doc_id=" + str(self.DocID)
|
||||
DB.Exec(self.sql)
|
||||
DB.Commit()
|
||||
db.runsql(self.sql)
|
||||
db.commit()
|
||||
self.data = {}
|
||||
|
||||
class DocFile:
|
||||
|
@ -312,6 +326,8 @@ class DocFile:
|
|||
An association between a document and a file.
|
||||
"""
|
||||
|
||||
import os.path
|
||||
|
||||
def Load(self, DocID, row):
|
||||
assert not DocID == None
|
||||
assert not row == None
|
||||
|
@ -319,19 +335,25 @@ class DocFile:
|
|||
self.Filename = trim(row[0])
|
||||
self.FormatID = row[1]
|
||||
if self.Filename[:5] == 'http:' or self.Filename[:4] == 'ftp:':
|
||||
self.Local = 0
|
||||
self.IsLocal = 0
|
||||
else:
|
||||
self.Local = 1
|
||||
|
||||
self.IsLocal = 1
|
||||
self.file_only = self.os.path.split(self.Filename)[1]
|
||||
self.basename = self.os.path.splitext(self.file_only)[0]
|
||||
|
||||
# FIXME: this is a stub. We need a new field in the database.
|
||||
|
||||
self.is_primary = self.IsLocal
|
||||
|
||||
def Save(self):
|
||||
self.sql = "UPDATE document_file SET format_id=" + dbint(self.FormatID) + " WHERE doc_id=" + str(self.DocID) + " AND filename=" + wsq(self.Filename)
|
||||
DB.Exec(self.sql)
|
||||
DB.Commit()
|
||||
db.runsql(self.sql)
|
||||
db.commit()
|
||||
|
||||
def Del(self):
|
||||
self.sql = "DELETE FROM document_file WHERE doc_id=" + str(self.DocID) + " AND filename=" + wsq(self.Filename)
|
||||
DB.Exec(self.sql)
|
||||
DB.Commit()
|
||||
db.runsql(self.sql)
|
||||
db.commit()
|
||||
|
||||
|
||||
# DocRatings
|
||||
|
@ -347,7 +369,7 @@ class DocRatings(LampadasCollection):
|
|||
assert not DocID == None
|
||||
self.DocID = DocID
|
||||
self.sql = "SELECT user_id, date_entered, vote FROM doc_vote WHERE doc_id=" + str(DocID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -369,12 +391,12 @@ class DocRatings(LampadasCollection):
|
|||
if self.data[UserID] == None: return
|
||||
del self.data[UserID]
|
||||
self.sql = 'DELETE FROM doc_vote WHERE doc_id=' + str(self.DocID) + ' AND user_id=' + str(UserID)
|
||||
DB.Exec(self.sql)
|
||||
db.runsql(self.sql)
|
||||
self.CalcAverage()
|
||||
|
||||
def Clear(self):
|
||||
self.sql = "DELETE FROM doc_vote WHERE doc_id=" + str(self.DocID)
|
||||
DB.Exec(self.sql)
|
||||
db.runsql(self.sql)
|
||||
self.data = {}
|
||||
self.CalcAverage()
|
||||
|
||||
|
@ -386,8 +408,8 @@ class DocRatings(LampadasCollection):
|
|||
self.Average = self.Average + self.data[key].Rating
|
||||
self.Average = self.Average / self.Count()
|
||||
self.sql = "UPDATE document SET rating=" + str(self.Average) + " WHERE doc_id=" + str(self.DocID)
|
||||
# DB.Exec(self.sql)
|
||||
# DB.Commit()
|
||||
# db.runsql(self.sql)
|
||||
# db.commit()
|
||||
if not self.Parent == None:
|
||||
self.Parent.Rating = self.Average
|
||||
|
||||
|
@ -406,10 +428,10 @@ class DocRating:
|
|||
|
||||
def Save(self):
|
||||
self.sql = "DELETE from doc_vote WHERE doc_id=" + str(self.DocID) + " AND user_id=" + str(self.UserID)
|
||||
DB.Exec(self.sql)
|
||||
db.runsql(self.sql)
|
||||
self.sql = "INSERT INTO doc_vote (doc_id, user_id, vote) VALUES (" + str(self.DocID) + ", " + str(self.UserID) + ", " + str(self.Rating) + ")"
|
||||
DB.Exec(self.sql)
|
||||
DB.Commit()
|
||||
db.runsql(self.sql)
|
||||
db.commit()
|
||||
|
||||
|
||||
# DocVersions
|
||||
|
@ -424,7 +446,7 @@ class DocVersions(LampadasCollection):
|
|||
assert not DocID == None
|
||||
self.DocID = DocID
|
||||
self.sql = "SELECT rev_id, version, pub_date, initials, notes FROM document_rev WHERE doc_id=" + str(DocID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -449,8 +471,8 @@ class DocVersion:
|
|||
|
||||
def Save(self):
|
||||
self.sql = "UPDATE document_rev SET version=" + wsq(self.Version) + ", pub_date=" + wsq(self.PubDate) + ", initials=" + wsq(self.Initials) + ", notes=" + wsq(self.Notes) + "WHERE doc_id=" + str(self.DocID) + " AND rev_id" + wsq(self.ID)
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
assert db.runsql(self.sql) == 1
|
||||
db.commit()
|
||||
|
||||
|
||||
# DTDs
|
||||
|
@ -463,7 +485,7 @@ class DTDs(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT dtd from dtd"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -494,7 +516,7 @@ class Errs(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT err_id FROM error"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -515,7 +537,7 @@ class Err:
|
|||
def Load(self, row):
|
||||
self.ErrID = trim(row[0])
|
||||
self.sql = "SELECT lang, err_name, err_desc FROM error_i18n WHERE err_id=" + wsq(self.ErrID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -543,7 +565,7 @@ class Formats(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT format_id FROM format"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -564,7 +586,7 @@ class Format:
|
|||
def Load(self, row):
|
||||
self.ID = row[0]
|
||||
self.sql = "SELECT lang, format_name, format_desc FROM format_i18n WHERE format_id=" + str(self.ID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -593,7 +615,7 @@ class Languages(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT isocode, supported FROM language"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -612,14 +634,14 @@ class Language:
|
|||
if LanguageCode == None: return
|
||||
self.Code = LanguageCode
|
||||
self.sql = "SELECT isocode, supported FROM language WHERE isocode= " + wsq(LanguageCode)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
self.Load(self.sql)
|
||||
|
||||
def Load(self, row):
|
||||
self.Code = trim(row[0])
|
||||
self.Supported = tf2bool(row[1])
|
||||
self.sql = "SELECT lang, language_name FROM language_i18n WHERE isocode=" + wsq(self.Code)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -646,7 +668,7 @@ class PubStatuses(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT pub_status FROM pub_status"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -668,7 +690,7 @@ class PubStatus:
|
|||
def Load(self, row):
|
||||
self.Code = trim(row[0])
|
||||
self.sql = "SELECT lang, pub_status_name, pub_status_desc FROM pub_status_i18n WHERE pub_status=" + wsq(self.Code)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -696,7 +718,7 @@ class ReviewStatuses(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT review_status FROM review_status"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -718,7 +740,7 @@ class ReviewStatus:
|
|||
def Load(self, row):
|
||||
self.Code = trim(row[0])
|
||||
self.sql = "SELECT lang, review_status_name, review_status_desc FROM review_status_i18n WHERE review_status=" + wsq(self.Code)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -746,7 +768,7 @@ class Topics(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT topic_num FROM topic"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -769,7 +791,7 @@ class Topic:
|
|||
def Load(self, row):
|
||||
self.Num = trim(row[0])
|
||||
self.sql = "SELECT lang, topic_name, topic_description FROM topic_i18n string_i18n WHERE topic_num=" + wsq(self.Num)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -793,19 +815,19 @@ class Users:
|
|||
"""
|
||||
|
||||
def Count(self):
|
||||
return DB.Value('SELECT count(*) from username')
|
||||
return db.value('SELECT count(*) from username')
|
||||
|
||||
def Add(self, Username, FirstName, MiddleName, Surname, Email, IsAdmin, IsSysadmin, Password, Notes, Stylesheet):
|
||||
self.id = DB.Value('SELECT max(user_id) from username') + 1
|
||||
self.id = db.value('SELECT max(user_id) from username') + 1
|
||||
self.sql = "INSERT INTO username (user_id, username, first_name, middle_name, surname, email, admin, sysadmin, password, notes, stylesheet) VALUES (" + str(self.id) + ", " + wsq(Username) + ", " + wsq(FirstName) + ", " + wsq(MiddleName) + ", " + wsq(Surname) + ", " + wsq(Email) + ", " + wsq(bool2tf(IsAdmin)) + ", " + wsq(bool2tf(IsSysadmin)) + ", " + wsq(Password) + ", " + wsq(Notes) + ", " + wsq(Stylesheet) + ")"
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
return DB.Value('SELECT max(user_id) from username')
|
||||
assert db.runsql(self.sql) == 1
|
||||
db.commit()
|
||||
return db.value('SELECT max(user_id) from username')
|
||||
|
||||
def Del(self, id):
|
||||
self.sql = ('DELETE from username WHERE user_id=' + str(id))
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
assert db.runsql(self.sql) == 1
|
||||
db.commit()
|
||||
|
||||
class User:
|
||||
"""
|
||||
|
@ -815,7 +837,7 @@ class User:
|
|||
|
||||
def __init__(self, id) :
|
||||
self.sql = 'SELECT user_id, username, session_id, first_name, middle_name, surname, email, admin, sysadmin, password, notes, stylesheet FROM username WHERE user_id=' + str(id)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
row = self.cursor.fetchone()
|
||||
self.ID = row[0]
|
||||
self.Username = trim(row[1])
|
||||
|
@ -845,55 +867,69 @@ class UserDocs(LampadasList):
|
|||
assert not UserID == None
|
||||
self.UserID = UserID
|
||||
self.sql = "SELECT doc_id, user_id, role, email, active FROM document_user WHERE user_id=" + str(self.UserID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
newUserDoc = UserDoc(UserID, row[0])
|
||||
newUserDoc.Load(row)
|
||||
newUserDoc = UserDoc(row[0], UserID)
|
||||
self.list = self.list + [newUserDoc]
|
||||
|
||||
def Add(self, DocID, Role, Email, Active):
|
||||
self.sql = "INSERT INTO document_user(doc_id, user_id, role, email, active) VALUES (" + str(DocID) + ", " + str(self.UserID) + ", " + wsq(Role) + ", " + wsq(Email) + ", " + wsq(bool2tf(Active)) + " )"
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
assert db.runsql(self.sql) == 1
|
||||
db.commit()
|
||||
|
||||
def Del(self, DocID):
|
||||
self.sql = ('DELETE from document_user WHERE doc_id=' + str(DocID) + ' AND user_id=' + str(self.UserID))
|
||||
assert DB.Exec(self.sql) == 1
|
||||
DB.Commit()
|
||||
assert db.runsql(self.sql) == 1
|
||||
db.commit()
|
||||
del self.col[DocID]
|
||||
|
||||
class UserDoc:
|
||||
"""
|
||||
An association between a user and a document. This association defines the role
|
||||
which the user plays in the production of the document.
|
||||
"""
|
||||
class UserDoc(Doc):
|
||||
"""
|
||||
An association between a user and a document. This association defines the role
|
||||
which the user plays in the production of the document.
|
||||
"""
|
||||
|
||||
def __init__(self, UserID=None, DocID=None):
|
||||
self.UserID = UserID
|
||||
self.DocID = DocID
|
||||
if DocID == None: return
|
||||
if UserID == None: return
|
||||
self.sql = "SELECT doc_id, user_id, role, email, active FROM document_user WHERE doc_id=" + str(DocID) + " AND user_id=" + str(UserID)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
row = self.cursor.fetchone()
|
||||
self.Load(row)
|
||||
def __init__(self, DocID=None, UserID=None):
|
||||
Doc.__init__(self)
|
||||
self.DocID = DocID
|
||||
self.UserID = UserID
|
||||
if DocID == None: return
|
||||
if UserID == None: return
|
||||
self.Load(DocID, UserID)
|
||||
|
||||
def Load(self, row):
|
||||
assert not row == None
|
||||
self.DocID = row[0]
|
||||
self.UserID = row[1]
|
||||
self.Role = trim(row[2])
|
||||
self.Email = trim(row[3])
|
||||
self.Active = tf2bool(row[4])
|
||||
def Load(self, DocID=None, UserID=None):
|
||||
if not DocID == None:
|
||||
self.DocID = DocID
|
||||
assert not self.DocID == None
|
||||
if not UserID == None:
|
||||
self.UserID = UserID
|
||||
assert not self.UserID == None
|
||||
sql = "SELECT doc_id, user_id, role, email, active FROM document_user WHERE doc_id=" + str(self.DocID) + " AND user_id=" + str(self.UserID)
|
||||
cursor = db.select(sql)
|
||||
row = cursor.fetchone()
|
||||
self.LoadRow(row)
|
||||
Doc.Load(self, self.DocID)
|
||||
|
||||
def Save(self):
|
||||
self.sql = "UPDATE document_user SET role=" + wsq(self.Role) + ", email=" + wsq(self.Email) + ", active=" + wsq(bool2tf(self.Active)) + " WHERE doc_id=" + str(self.DocID) + " AND user_id=" + str(self.UserID)
|
||||
DB.Exec(self.sql)
|
||||
DB.Commit()
|
||||
def LoadRow(self, row):
|
||||
assert not row == None
|
||||
self.DocID = row[0]
|
||||
self.UserID = row[1]
|
||||
self.Role = trim(row[2])
|
||||
self.Email = trim(row[3])
|
||||
self.Active = tf2bool(row[4])
|
||||
|
||||
def Save(self):
|
||||
self.sql = "UPDATE document_user SET role=" + wsq(self.Role) + ", email=" + wsq(self.Email) + ", active=" + wsq(bool2tf(self.Active)) + " WHERE doc_id=" + str(self.DocID) + " AND user_id=" + str(self.UserID)
|
||||
db.runsql(self.sql)
|
||||
db.commit()
|
||||
Doc.Save(self)
|
||||
|
||||
|
||||
lampadas = Lampadas()
|
||||
|
||||
|
||||
# main
|
||||
if __name__ == '__main__' :
|
||||
print "Running unit tests..."
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Database Module
|
||||
|
||||
|
@ -9,113 +27,102 @@ This module generates a Database object for accessing a back-end RDBMS
|
|||
# Modules ##################################################################
|
||||
|
||||
import pyPgSQL
|
||||
import Config
|
||||
import Log
|
||||
from Config import config
|
||||
from Log import log
|
||||
|
||||
# Database
|
||||
|
||||
class UnknownDBException(Exception):
|
||||
pass
|
||||
pass
|
||||
|
||||
class Database:
|
||||
"""
|
||||
The database contains all users and documents
|
||||
"""
|
||||
"""
|
||||
The database contains all users and documents
|
||||
"""
|
||||
|
||||
Config = Config.Config()
|
||||
Log = Log.Log()
|
||||
Connected = 0
|
||||
connected = 0
|
||||
|
||||
def __del__(self):
|
||||
if self.Connected:
|
||||
self.db.connection.close()
|
||||
|
||||
def Connect(self, dbtype, dbname):
|
||||
"""
|
||||
Connect to the database specified in Config.
|
||||
"""
|
||||
def __del__(self):
|
||||
if self.connected:
|
||||
self.database.connection.close()
|
||||
|
||||
def connect(self, db_type, db_name):
|
||||
"""
|
||||
Connect to the database specified in Config.
|
||||
"""
|
||||
|
||||
if dbname == '':
|
||||
raise UnknownDBException('Database name not specified')
|
||||
elif dbtype == 'pgsql':
|
||||
self.db = PgSQLDatabase(dbname)
|
||||
self.Connected = 1
|
||||
else:
|
||||
raise UnknownDBException('Unknown database type %s' % dbtype)
|
||||
if db_name == '':
|
||||
raise UnknownDBException('Database name not specified')
|
||||
elif db_type == 'pgsql':
|
||||
self.database = PgSQLDatabase(db_name)
|
||||
self.connected = 1
|
||||
else:
|
||||
raise UnknownDBException('Unknown database type %s' % db_type)
|
||||
|
||||
# self.Log(3, 'Thread safety ' + str(self.db.connection.threadsafety()))
|
||||
def connection(self):
|
||||
return self.database.connection
|
||||
|
||||
def Connection(self):
|
||||
return self.db.connection
|
||||
def cursor(self):
|
||||
return self.database.connection.cursor()
|
||||
|
||||
def Cursor(self):
|
||||
return self.db.connection.cursor()
|
||||
# FIXME : the python DB-API 2.0 states that you can transfer the burden
|
||||
# of quoting values to the cursor as in
|
||||
#
|
||||
# sql = "select * from document where doc_id = %(did)s"
|
||||
# param = {'did':'123'}
|
||||
# my_cursor.execute(sql,param)
|
||||
#
|
||||
# I like Python :-)
|
||||
#
|
||||
def select(self, sql):
|
||||
if config.log_sql:
|
||||
log(3, sql)
|
||||
self.cursor = self.database.connection.cursor()
|
||||
self.cursor.execute(sql)
|
||||
return self.cursor
|
||||
|
||||
# FIXME : the python DB-API 2.0 states that you can transfer the burden
|
||||
# of quoting values to the cursor as in
|
||||
#
|
||||
# sql = "select * from document where doc_id = %(did)s"
|
||||
# param = {'did':'123'}
|
||||
# my_cursor.execute(sql,param)
|
||||
#
|
||||
# I like Python :-)
|
||||
#
|
||||
def Select(self, sql):
|
||||
if self.Config.LogSQL:
|
||||
self.Log(3, sql)
|
||||
self.cursor = self.db.connection.cursor()
|
||||
self.cursor.execute(sql)
|
||||
return self.cursor
|
||||
def value(self, sql):
|
||||
if config.log_sql:
|
||||
log(3, sql)
|
||||
self.cursor = self.database.connection.cursor()
|
||||
self.cursor.execute(sql)
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None:
|
||||
self.value = None
|
||||
else:
|
||||
self.value = self.row[0]
|
||||
return self.value
|
||||
|
||||
def Value(self, sql):
|
||||
if self.Config.LogSQL:
|
||||
self.Log(3, sql)
|
||||
self.cursor = self.db.connection.cursor()
|
||||
self.cursor.execute(sql)
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None:
|
||||
self.value = None
|
||||
else:
|
||||
self.value = self.row[0]
|
||||
return self.value
|
||||
def runsql(self, sql):
|
||||
if config.log_sql:
|
||||
log(3, sql)
|
||||
self.cursor = self.database.connection.cursor()
|
||||
self.cursor.execute(sql)
|
||||
return self.cursor.rowcount
|
||||
|
||||
def Exec(self, sql):
|
||||
if self.Config.LogSQL:
|
||||
self.Log(3, sql)
|
||||
self.cursor = self.db.connection.cursor()
|
||||
self.cursor.execute(sql)
|
||||
return self.cursor.rowcount
|
||||
|
||||
def Commit(self):
|
||||
self.Log(3, 'Committing database')
|
||||
self.db.connection.commit()
|
||||
def commit(self):
|
||||
log(3, 'Committing database')
|
||||
self.database.connection.commit()
|
||||
|
||||
|
||||
# Specific derived DB classes ##################################################
|
||||
|
||||
class PgSQLDatabase(Database):
|
||||
|
||||
def __init__(self,dbname):
|
||||
from pyPgSQL import PgSQL
|
||||
self.connection = PgSQL.connect(database=dbname)
|
||||
def __init__(self,db_name):
|
||||
from pyPgSQL import PgSQL
|
||||
self.connection = PgSQL.connect(database=db_name)
|
||||
|
||||
# except ImportError:
|
||||
# # PostgresSQL back-end is not available
|
||||
# pass
|
||||
|
||||
class MySQLDatabase(Database):
|
||||
|
||||
def __init__(self,dbname):
|
||||
from pyMySQL import MySQL
|
||||
self.cnx = MySQL.connection(dbname=dbname)
|
||||
def __init__(self,db_name):
|
||||
from pyMySQL import MySQL
|
||||
self.cnx = MySQL.connection(db_name=db_name)
|
||||
|
||||
# except ImportError:
|
||||
# # MySQL back-end is not available
|
||||
# pass
|
||||
db = Database()
|
||||
db.connect(config.db_type, config.db_name)
|
||||
|
||||
|
||||
# main
|
||||
if __name__ == '__main__':
|
||||
print "Running unit tests..."
|
||||
print "Unit tests run."
|
||||
print "Running unit tests..."
|
||||
print "Unit tests run."
|
||||
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
The Globals module implements low level utility and convenience routines.
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas HTML Primitives Module
|
||||
|
||||
|
@ -10,20 +28,20 @@ to the Lampadas system.
|
|||
# Modules ##################################################################
|
||||
|
||||
from Globals import *
|
||||
from Config import Config
|
||||
from Log import Log
|
||||
from Config import config
|
||||
from Log import log
|
||||
from URLParse import URI
|
||||
from DataLayer import Lampadas
|
||||
import WebLayer
|
||||
|
||||
import commands
|
||||
from string import split
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
# Globals
|
||||
|
||||
Config = Config()
|
||||
Log = Log()
|
||||
L = Lampadas()
|
||||
|
||||
|
||||
|
@ -36,385 +54,375 @@ EDIT_ICON = '<img src="images/edit.png" alt="Edit" height="20" width="20" border
|
|||
|
||||
class ComboFactory:
|
||||
|
||||
def Class(self, value, lang):
|
||||
self.combo = "<select name='class'>\n"
|
||||
keys = L.Classes.keys()
|
||||
for key in keys:
|
||||
classfoo = L.Classes[key]
|
||||
assert not classfoo == None
|
||||
self.combo = self.combo + "<option "
|
||||
if classfoo.ID == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(classfoo.ID) + "'>"
|
||||
self.combo = self.combo + classfoo.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
def Class(self, value, lang):
|
||||
self.combo = "<select name='class'>\n"
|
||||
keys = L.Classes.keys()
|
||||
for key in keys:
|
||||
classfoo = L.Classes[key]
|
||||
assert not classfoo == None
|
||||
self.combo = self.combo + "<option "
|
||||
if classfoo.ID == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(classfoo.ID) + "'>"
|
||||
self.combo = self.combo + classfoo.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
def Doc(self, value, lang):
|
||||
self.combo = "<select name='doc'>\n"
|
||||
keys = L.Docs.keys()
|
||||
for key in keys:
|
||||
doc = L.Docs[key]
|
||||
assert not doc == None
|
||||
if doc.LanguageCode == lang or lang == None:
|
||||
self.combo = self.combo + "<option "
|
||||
if doc.ID == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(doc.ID) + "'>"
|
||||
self.combo = self.combo + doc.Title
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
def Doc(self, value, lang):
|
||||
self.combo = "<select name='doc'>\n"
|
||||
keys = L.Docs.keys()
|
||||
for key in keys:
|
||||
doc = L.Docs[key]
|
||||
assert not doc == None
|
||||
if doc.LanguageCode == lang or lang == None:
|
||||
self.combo = self.combo + "<option "
|
||||
if doc.ID == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(doc.ID) + "'>"
|
||||
self.combo = self.combo + doc.Title
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
def DTD(self, value, lang):
|
||||
self.combo = "<select name='dtd'>\n"
|
||||
keys = L.DTDs.keys()
|
||||
for key in keys:
|
||||
dtd = L.DTDs[key]
|
||||
assert not dtd == None
|
||||
self.combo = self.combo + "<option "
|
||||
if dtd.DTD == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + dtd.DTD + "'>"
|
||||
self.combo = self.combo + dtd.DTD
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
def Format(self, value, lang):
|
||||
self.combo = "<select name='format'>\n"
|
||||
keys = L.Formats.keys()
|
||||
for key in keys:
|
||||
format = L.Formats[key]
|
||||
assert not format == None
|
||||
self.combo = self.combo + "<option "
|
||||
if format.ID == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(format.ID) + "'>"
|
||||
self.combo = self.combo + format.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
def DTD(self, value, lang):
|
||||
self.combo = "<select name='dtd'>\n"
|
||||
keys = L.DTDs.keys()
|
||||
for key in keys:
|
||||
dtd = L.DTDs[key]
|
||||
assert not dtd == None
|
||||
self.combo = self.combo + "<option "
|
||||
if dtd.DTD == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + dtd.DTD + "'>"
|
||||
self.combo = self.combo + dtd.DTD
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
def Format(self, value, lang):
|
||||
self.combo = "<select name='format'>\n"
|
||||
keys = L.Formats.keys()
|
||||
for key in keys:
|
||||
format = L.Formats[key]
|
||||
assert not format == None
|
||||
self.combo = self.combo + "<option "
|
||||
if format.ID == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(format.ID) + "'>"
|
||||
self.combo = self.combo + format.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
def Language(self, value, lang):
|
||||
return "lang"
|
||||
def Language(self, value, lang):
|
||||
return "lang"
|
||||
|
||||
def License(self, value, lang):
|
||||
return "license"
|
||||
def License(self, value, lang):
|
||||
return "license"
|
||||
|
||||
def PubStatus(self, value, lang):
|
||||
self.combo = "<select name='pub_status'>\n"
|
||||
keys = L.PubStatuses.keys()
|
||||
for key in keys:
|
||||
PubStatus = L.PubStatuses[key]
|
||||
assert not PubStatus == None
|
||||
self.combo = self.combo + "<option "
|
||||
if PubStatus.Code == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(PubStatus.Code) + "'>"
|
||||
self.combo = self.combo + PubStatus.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
def ReviewStatus(self, value, lang):
|
||||
self.combo = "<select name='review_status'>\n"
|
||||
keys = L.ReviewStatuses.keys()
|
||||
for key in keys:
|
||||
ReviewStatus = L.ReviewStatuses[key]
|
||||
assert not ReviewStatus == None
|
||||
self.combo = self.combo + "<option "
|
||||
if ReviewStatus.Code == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(ReviewStatus.Code) + "'>"
|
||||
self.combo = self.combo + ReviewStatus.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
def PubStatus(self, value, lang):
|
||||
self.combo = "<select name='pub_status'>\n"
|
||||
keys = L.PubStatuses.keys()
|
||||
for key in keys:
|
||||
PubStatus = L.PubStatuses[key]
|
||||
assert not PubStatus == None
|
||||
self.combo = self.combo + "<option "
|
||||
if PubStatus.Code == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(PubStatus.Code) + "'>"
|
||||
self.combo = self.combo + PubStatus.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
def ReviewStatus(self, value, lang):
|
||||
self.combo = "<select name='review_status'>\n"
|
||||
keys = L.ReviewStatuses.keys()
|
||||
for key in keys:
|
||||
ReviewStatus = L.ReviewStatuses[key]
|
||||
assert not ReviewStatus == None
|
||||
self.combo = self.combo + "<option "
|
||||
if ReviewStatus.Code == value:
|
||||
self.combo = self.combo + "selected "
|
||||
self.combo = self.combo + "value='" + str(ReviewStatus.Code) + "'>"
|
||||
self.combo = self.combo + ReviewStatus.I18n[lang].Name
|
||||
self.combo = self.combo + "</option>\n"
|
||||
self.combo = self.combo + "</select>"
|
||||
return self.combo
|
||||
|
||||
|
||||
# BoxFactory
|
||||
|
||||
class BoxFactory:
|
||||
|
||||
def MainMenu(self, lang):
|
||||
self.box = ''
|
||||
self.box = self.box + '<table class="navbox"><tr><th>|mmtitle|</th></tr>'
|
||||
self.box = self.box + '<tr><td>'
|
||||
self.box = self.box + '<a href="home">|home|</a><br>'
|
||||
self.box = self.box + '<a href="doctable">|doctable|</a><br>'
|
||||
self.box = self.box + '<a href="downloads">Downloads</a>'
|
||||
self.box = self.box + '</td></tr>'
|
||||
self.box = self.box + '</table>'
|
||||
return self.box
|
||||
def MainMenu(self, lang):
|
||||
self.box = ''
|
||||
self.box = self.box + '<table class="navbox"><tr><th>|mmtitle|</th></tr>'
|
||||
self.box = self.box + '<tr><td>'
|
||||
self.box = self.box + '<a href="home">|home|</a><br>'
|
||||
self.box = self.box + '<a href="doctable">|doctable|</a><br>'
|
||||
self.box = self.box + '<a href="downloads">Downloads</a>'
|
||||
self.box = self.box + '</td></tr>'
|
||||
self.box = self.box + '</table>'
|
||||
return self.box
|
||||
|
||||
|
||||
class TableFactory:
|
||||
|
||||
Combo = ComboFactory()
|
||||
Combo = ComboFactory()
|
||||
|
||||
def BarGraph(self, value, max, lang):
|
||||
return str(value) + '/' + str(max)
|
||||
def BarGraph(self, value, max, lang):
|
||||
return str(value) + '/' + str(max)
|
||||
|
||||
def Doc(self, DocID, lang):
|
||||
self.box = ''
|
||||
self.box = self.box + '<table class="box" style="width:100%"><tr><th colspan="6">|docdetails|</th></tr>'
|
||||
if DocID:
|
||||
Doc = L.Docs[DocID]
|
||||
self.box = self.box + '<form method=POST action="docsave" name="document">'
|
||||
else:
|
||||
Doc = Doc()
|
||||
self.box = self.box + '<form method=POST action="docadd" name="document">'
|
||||
|
||||
self.box = self.box + '<input name="doc_id" type=hidden value=' + str(Doc.ID) + '>\n'
|
||||
self.box = self.box + '<tr>\n'
|
||||
self.box = self.box + '<th align=right>Title</th><td colspan=5><input type=text name=title size=60 style="width:100%" value="' + Doc.Title + '"></td>\n'
|
||||
self.box = self.box + '</tr>\n'
|
||||
self.box = self.box + '<tr>\n'
|
||||
self.box = self.box + '<th align=right>'
|
||||
if Doc.URL:
|
||||
self.box = self.box + '<a href="' + Doc.URL + '">URL</a>'
|
||||
else:
|
||||
self.box = self.box + 'URL'
|
||||
self.box = self.box + '</th><td colspan=5><input type=text name=url size=60 style="width:100%" value="' + Doc.URL + '"></td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>'
|
||||
def Doc(self, DocID, lang):
|
||||
self.box = ''
|
||||
self.box = self.box + '<table class="box" style="width:100%"><tr><th colspan="6">|docdetails|</th></tr>'
|
||||
if DocID:
|
||||
Doc = L.Docs[DocID]
|
||||
self.box = self.box + '<form method=POST action="docsave" name="document">'
|
||||
else:
|
||||
Doc = Doc()
|
||||
self.box = self.box + '<form method=POST action="docadd" name="document">'
|
||||
|
||||
self.box = self.box + '<input name="doc_id" type=hidden value=' + str(Doc.ID) + '>\n'
|
||||
self.box = self.box + '<tr>\n'
|
||||
self.box = self.box + '<th align=right>Title</th><td colspan=5><input type=text name=title size=60 style="width:100%" value="' + Doc.Title + '"></td>\n'
|
||||
self.box = self.box + '</tr>\n'
|
||||
self.box = self.box + '<tr>\n'
|
||||
self.box = self.box + '<th align=right>'
|
||||
if Doc.URL:
|
||||
self.box = self.box + '<a href="' + Doc.URL + '">URL</a>'
|
||||
else:
|
||||
self.box = self.box + 'URL'
|
||||
self.box = self.box + '</th><td colspan=5><input type=text name=url size=60 style="width:100%" value="' + Doc.URL + '"></td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>'
|
||||
|
||||
if Doc.HomeURL:
|
||||
self.box = self.box + '<a href="' + Doc.HomeURL + '">Home URL</a>'
|
||||
else:
|
||||
self.box = self.box + 'Home URL'
|
||||
self.box = self.box + '</th><td colspan=5><input type=text name=ref_url size=60 style="width:100%" value="' + Doc.HomeURL + '"></td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Status</th><td>'
|
||||
self.box = self.box + self.Combo.PubStatus(Doc.PubStatusCode, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Class</th><td>\n'
|
||||
self.box = self.box + self.Combo.Class(Doc.ClassID, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Maint</th><td>\n'
|
||||
if Doc.Maintained:
|
||||
self.box = self.box + "Yes"
|
||||
else:
|
||||
self.box = self.box + "No"
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Language</th><td>'
|
||||
self.box = self.box + self.Combo.ReviewStatus(Doc.ReviewStatus, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Accuracy</th><td>'
|
||||
self.box = self.box + self.Combo.ReviewStatus(Doc.TechReviewStatus, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>License</th><td>'
|
||||
self.box = self.box + self.Combo.License(Doc.License, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Pub Date</th><td><input type=text name=pub_date size=10 value="' + Doc.PubDate + '"></td>'
|
||||
self.box = self.box + '<th align=right>Updated</th><td><input type=text name=last_update size=10 value="' + Doc.LastUpdate + '"></td>'
|
||||
self.box = self.box + '<th align=right>Version</th><td><input type=text name=version size=10 value="' + Doc.Version + '"></td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Tickle Date</th><td><input type=text name=tickle_date size=10 value="' + Doc.TickleDate + '"></td>'
|
||||
self.box = self.box + '<th align=right>ISBN</th><td><input type=text name=isbn size=14 value="' + Doc.ISBN + '"></td>'
|
||||
self.box = self.box + '<th align=right>Rating</th>\n'
|
||||
self.box = self.box + '<td>'
|
||||
self.box = self.box + self.BarGraph(Doc.Rating, 10, lang)
|
||||
self.box = self.box + '</td>\n'
|
||||
if DocID:
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Format</th><td>'
|
||||
self.box = self.box + L.Formats[Doc.FormatID].I18n[lang].Name
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>DTD</th><td>'
|
||||
self.box = self.box + Doc.DTD + ' ' + Doc.DTDVersion
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Lang</th><td>'
|
||||
self.box = self.box + self.Combo.Language(Doc.Lang, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Abstract</th>'
|
||||
self.box = self.box + '<td colspan=5><textarea name=abstract rows=6 cols=40 style="width:100%" wrap>' + Doc.Abstract + '</textarea></td>\n'
|
||||
self.box = self.box + '</tr>\n'
|
||||
self.box = self.box + '<tr><td></td><td><input type=submit name=save value=Save></td></tr>\n'
|
||||
self.box = self.box + '</form>\n'
|
||||
self.box = self.box + '</table>\n'
|
||||
if Doc.HomeURL:
|
||||
self.box = self.box + '<a href="' + Doc.HomeURL + '">Home URL</a>'
|
||||
else:
|
||||
self.box = self.box + 'Home URL'
|
||||
self.box = self.box + '</th><td colspan=5><input type=text name=ref_url size=60 style="width:100%" value="' + Doc.HomeURL + '"></td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Status</th><td>'
|
||||
self.box = self.box + self.Combo.PubStatus(Doc.PubStatusCode, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Class</th><td>\n'
|
||||
self.box = self.box + self.Combo.Class(Doc.ClassID, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Maint</th><td>\n'
|
||||
if Doc.Maintained:
|
||||
self.box = self.box + "Yes"
|
||||
else:
|
||||
self.box = self.box + "No"
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Language</th><td>'
|
||||
self.box = self.box + self.Combo.ReviewStatus(Doc.ReviewStatus, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Accuracy</th><td>'
|
||||
self.box = self.box + self.Combo.ReviewStatus(Doc.TechReviewStatus, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>License</th><td>'
|
||||
self.box = self.box + self.Combo.License(Doc.License, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Pub Date</th><td><input type=text name=pub_date size=10 value="' + Doc.PubDate + '"></td>'
|
||||
self.box = self.box + '<th align=right>Updated</th><td><input type=text name=last_update size=10 value="' + Doc.LastUpdate + '"></td>'
|
||||
self.box = self.box + '<th align=right>Version</th><td><input type=text name=version size=10 value="' + Doc.Version + '"></td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Tickle Date</th><td><input type=text name=tickle_date size=10 value="' + Doc.TickleDate + '"></td>'
|
||||
self.box = self.box + '<th align=right>ISBN</th><td><input type=text name=isbn size=14 value="' + Doc.ISBN + '"></td>'
|
||||
self.box = self.box + '<th align=right>Rating</th>\n'
|
||||
self.box = self.box + '<td>'
|
||||
self.box = self.box + self.BarGraph(Doc.Rating, 10, lang)
|
||||
self.box = self.box + '</td>\n'
|
||||
if DocID:
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Format</th><td>'
|
||||
self.box = self.box + L.Formats[Doc.FormatID].I18n[lang].Name
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>DTD</th><td>'
|
||||
self.box = self.box + Doc.DTD + ' ' + Doc.DTDVersion
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '<th align=right>Lang</th><td>'
|
||||
self.box = self.box + self.Combo.Language(Doc.Lang, lang)
|
||||
self.box = self.box + '</td>'
|
||||
self.box = self.box + '</tr>\n<tr>\n'
|
||||
self.box = self.box + '<th align=right>Abstract</th>'
|
||||
self.box = self.box + '<td colspan=5><textarea name=abstract rows=6 cols=40 style="width:100%" wrap>' + Doc.Abstract + '</textarea></td>\n'
|
||||
self.box = self.box + '</tr>\n'
|
||||
self.box = self.box + '<tr><td></td><td><input type=submit name=save value=Save></td></tr>\n'
|
||||
self.box = self.box + '</form>\n'
|
||||
self.box = self.box + '</table>\n'
|
||||
|
||||
return self.box
|
||||
return self.box
|
||||
|
||||
def Docs(self, lang):
|
||||
self.box = ''
|
||||
self.box = self.box + '<table class="box"><tr><th colspan="2">Title</th></tr>'
|
||||
keys = L.Docs.keys()
|
||||
for key in keys:
|
||||
if L.Docs[key].Lang == lang:
|
||||
self.box = self.box + '<tr>'
|
||||
self.box = self.box + '<td><a href="editdoc/' + str(L.Docs[key].ID) + '">' + EDIT_ICON + '</a></td>'
|
||||
self.box = self.box + '<td><a href="' + str(L.Docs[key].URL) + '">' + L.Docs[key].Title + '</a></td>'
|
||||
self.box = self.box + '</tr>'
|
||||
self.box = self.box + '</table>'
|
||||
return self.box
|
||||
def Docs(self, lang):
|
||||
self.box = ''
|
||||
self.box = self.box + '<table class="box"><tr><th colspan="2">Title</th></tr>'
|
||||
keys = L.Docs.keys()
|
||||
for key in keys:
|
||||
if L.Docs[key].Lang == lang:
|
||||
self.box = self.box + '<tr>'
|
||||
self.box = self.box + '<td><a href="/editdoc/' + str(L.Docs[key].ID) + '/">' + EDIT_ICON + '</a></td>'
|
||||
self.box = self.box + '<td><a href="/doc/' + str(L.Docs[key].ID) + '/">' + L.Docs[key].Title + '</a></td>'
|
||||
self.box = self.box + '</tr>'
|
||||
self.box = self.box + '</table>'
|
||||
return self.box
|
||||
|
||||
|
||||
# PageFactory
|
||||
|
||||
class PageFactory:
|
||||
|
||||
Pages = WebLayer.Pages()
|
||||
Blocks = WebLayer.Blocks()
|
||||
Strings = WebLayer.Strings()
|
||||
Templates = WebLayer.Templates()
|
||||
Box = BoxFactory()
|
||||
Table = TableFactory()
|
||||
Pages = WebLayer.Pages()
|
||||
Blocks = WebLayer.Blocks()
|
||||
Strings = WebLayer.Strings()
|
||||
Templates = WebLayer.Templates()
|
||||
Box = BoxFactory()
|
||||
Table = TableFactory()
|
||||
|
||||
def __call__(self, key, lang):
|
||||
return self.Page(key, lang)
|
||||
def __call__(self, key, lang):
|
||||
return self.Page(key, lang)
|
||||
|
||||
def Page(self, key, lang):
|
||||
if key == '' or key == '/':
|
||||
key='home'
|
||||
if key[0] == '/':
|
||||
key = key[1:]
|
||||
Keys = split(key, '/')
|
||||
|
||||
# Allow the language to be specified in the URL
|
||||
#
|
||||
Log.Write(3, 'Testing language ' + Keys[0])
|
||||
forcelang = 0
|
||||
if Keys[0] in L.Languages.keys():
|
||||
Log.Write(3, 'URL specified the ' + Keys[0] + ' translation')
|
||||
if L.Languages[Keys[0]].Supported:
|
||||
lang = Keys[0]
|
||||
forcelang = 1
|
||||
else:
|
||||
Log.Write(3, 'Language ' + Keys[0] + ' not supported')
|
||||
Keys = Keys[1:]
|
||||
|
||||
Log.Write(3, 'Serving language ' + lang)
|
||||
pagecode = Keys[0]
|
||||
Log.Write(3, 'Building page ' + pagecode)
|
||||
if pagecode == 'doc':
|
||||
DocID = int(Keys[1])
|
||||
page = self.DocPage(DocID, lang)
|
||||
else:
|
||||
Page = self.Pages[pagecode]
|
||||
if Page == None:
|
||||
Page = self.Pages['404']
|
||||
assert not Page == None
|
||||
Template = self.Templates[Page.TemplateCode]
|
||||
assert not Template == None
|
||||
page = Template.Template
|
||||
def Page(self, key):
|
||||
uri = URI(key)
|
||||
uri.printdebug()
|
||||
Log.Write(3, 'Serving language ' + uri.Language)
|
||||
|
||||
if uri.Service == 'doc':
|
||||
if uri.Format == '':
|
||||
page = self.DocPage(uri)
|
||||
else:
|
||||
Page = self.Pages[uri.Filename]
|
||||
if Page == None:
|
||||
Page = self.Pages['404']
|
||||
assert not Page == None
|
||||
page = self.build_page(Page, uri)
|
||||
|
||||
page = page.replace('\|', 'DCM_PIPE')
|
||||
|
||||
pos = page.find('|')
|
||||
while pos <> -1 :
|
||||
pos2 = page.find('|', pos+1)
|
||||
if pos2 == -1:
|
||||
pos = -1
|
||||
else:
|
||||
oldstring = page[pos:pos2+1]
|
||||
token = page[pos+1:pos2]
|
||||
|
||||
newstring = ''
|
||||
|
||||
# Built-ins
|
||||
|
||||
if token=='title':
|
||||
newstring = Page.I18n[lang].Title
|
||||
if token=='body':
|
||||
newstring = Page.I18n[lang].Page
|
||||
if token=='hostname':
|
||||
newstring = Config.Hostname
|
||||
if token=='rootdir':
|
||||
newstring = Config.RootDir
|
||||
if token=='port':
|
||||
newstring = str(Config.Port)
|
||||
if token=='base':
|
||||
newstring = 'http://' + Config.Hostname + ':' + str(Config.Port) + Config.RootDir
|
||||
if forcelang:
|
||||
newstring = newstring + lang + '/'
|
||||
if token=='page':
|
||||
newstring = pagecode
|
||||
if token=='stylesheet':
|
||||
newstring='default' #FIXME
|
||||
return page
|
||||
|
||||
|
||||
# Boxes
|
||||
#
|
||||
if token=='boxmainmenu':
|
||||
newstring = self.Box.MainMenu(lang)
|
||||
|
||||
# Tables
|
||||
#
|
||||
if token=='tabdocstable':
|
||||
newstring = self.Table.Docs(lang)
|
||||
|
||||
if token=='tabeditdoc':
|
||||
DocID = int(Keys[1])
|
||||
newstring = self.Table.Doc(DocID, lang)
|
||||
|
||||
# Blocks and Strings
|
||||
#
|
||||
if newstring == '':
|
||||
Block = self.Blocks[token]
|
||||
if Block == None:
|
||||
String = self.Strings[token]
|
||||
if String == None:
|
||||
newstring = 'ERROR'
|
||||
Log.Write(1, 'Could not replace token ' + token)
|
||||
else:
|
||||
newstring = String.I18n[lang].String
|
||||
else:
|
||||
newstring = Block.I18n[lang].Block
|
||||
|
||||
if newstring == '':
|
||||
Log.Write(1, 'Could not replace token ' + token)
|
||||
else:
|
||||
page = page.replace(page[pos:pos2+1], newstring)
|
||||
page = page.replace('\|', 'DCM_PIPE')
|
||||
|
||||
pos = page.find('|')
|
||||
|
||||
page = page.replace('DCM_PIPE', '|')
|
||||
|
||||
Log.Write(3, 'Page built ' + pagecode)
|
||||
return page
|
||||
def build_page(self, Page, uri):
|
||||
Template = self.Templates[Page.TemplateCode]
|
||||
assert not Template == None
|
||||
page = Template.Template
|
||||
|
||||
def DocPage(self, DocID, lang):
|
||||
Doc = L.Docs[DocID]
|
||||
if Doc == None:
|
||||
page = "Error, could not locate document " + str(DocID)
|
||||
else:
|
||||
docformat = L.Formats[Doc.FormatID].I18n[lang].Name
|
||||
if docformat=='SGML' or docformat=='XML':
|
||||
Files = Doc.Files
|
||||
if Files.Count() == 0:
|
||||
page = 'No file to process'
|
||||
elif Files.Count() > 1:
|
||||
page = 'Only single files supported right now'
|
||||
else:
|
||||
keys = Files.keys()
|
||||
for key in keys:
|
||||
File = Files[key]
|
||||
page = page.replace('\|', 'DCM_PIPE')
|
||||
|
||||
pos = page.find('|')
|
||||
while pos <> -1 :
|
||||
pos2 = page.find('|', pos+1)
|
||||
if pos2 == -1:
|
||||
pos = -1
|
||||
else:
|
||||
oldstring = page[pos:pos2+1]
|
||||
token = page[pos+1:pos2]
|
||||
|
||||
newstring = ''
|
||||
|
||||
# Built-ins
|
||||
#
|
||||
if token=='title':
|
||||
newstring = Page.I18n[uri.Language].Title
|
||||
if token=='body':
|
||||
newstring = Page.I18n[uri.Language].Page
|
||||
if token=='hostname':
|
||||
newstring = config.hostname
|
||||
if token=='rootdir':
|
||||
newstring = config.root_dir
|
||||
if token=='port':
|
||||
newstring = str(config.pport)
|
||||
if token=='base':
|
||||
newstring = 'http://' + config.hostname + ':' + str(config.port) + config.root_dir
|
||||
if uri.ForceLang:
|
||||
newstring = newstring + uri.Language + '/'
|
||||
if token=='page':
|
||||
newstring = Page.Code
|
||||
if token=='stylesheet':
|
||||
newstring='default'
|
||||
|
||||
# FIXME: This must process the XML file that came out of
|
||||
# Converter(), not the source file.
|
||||
# Boxes
|
||||
#
|
||||
if token=='boxmainmenu':
|
||||
newstring = self.Box.MainMenu(uri.Language)
|
||||
|
||||
# Tables
|
||||
#
|
||||
if token=='tabdocstable':
|
||||
newstring = self.Table.Docs(uri.Language)
|
||||
|
||||
if token=='tabeditdoc':
|
||||
newstring = self.Table.Doc(uri.ID, uri.Language)
|
||||
|
||||
# Blocks and Strings
|
||||
#
|
||||
if newstring == '':
|
||||
Block = self.Blocks[token]
|
||||
if Block == None:
|
||||
String = self.Strings[token]
|
||||
if String == None:
|
||||
newstring = 'ERROR'
|
||||
Log.Write(1, 'Could not replace token ' + token)
|
||||
else:
|
||||
newstring = String.I18n[uri.Language].String
|
||||
else:
|
||||
newstring = Block.I18n[uri.Language].Block
|
||||
|
||||
if newstring == '':
|
||||
Log.Write(1, 'Could not replace token ' + token)
|
||||
else:
|
||||
page = page.replace(page[pos:pos2+1], newstring)
|
||||
page = page.replace('\|', 'DCM_PIPE')
|
||||
|
||||
pos = page.find('|')
|
||||
|
||||
page = page.replace('DCM_PIPE', '|')
|
||||
|
||||
Log.Write(3, 'Page built ' + Page.Code)
|
||||
return page
|
||||
|
||||
command = 'xsltproc /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/docbook.xsl ' + Config.CVSRoot + File.Filename
|
||||
page = commands.getoutput(command)
|
||||
else:
|
||||
page = 'FORMAT ' + docformat + ' NOT YET SUPPORTED'
|
||||
return page
|
||||
def DocPage(self, uri):
|
||||
DocID = uri.ID
|
||||
lang = uri.Language
|
||||
Doc = L.Docs[DocID]
|
||||
if Doc == None:
|
||||
page = "Error, could not locate document " + str(DocID)
|
||||
else:
|
||||
cachedir = config.cache_dir + str(Doc.ID) + '/'
|
||||
|
||||
Files = Doc.Files
|
||||
if Files.Count() == 0:
|
||||
page = 'No file to process'
|
||||
elif Files.Count() > 1:
|
||||
page = 'Only single files supported right now'
|
||||
else:
|
||||
command = 'cd ' + cachedir + '; make index'
|
||||
os.system(command)
|
||||
|
||||
if uri.Filename == '':
|
||||
uri.Filename = 'index.html'
|
||||
|
||||
if os.access(cachedir + uri.Filename, os.F_OK):
|
||||
fh = open(cachedir + uri.Filename)
|
||||
page = fh.read()
|
||||
fh.close()
|
||||
else:
|
||||
page = 'Document cannot be found'
|
||||
return page
|
||||
|
||||
|
||||
def main():
|
||||
F = PageFactory()
|
||||
for arg in sys.argv[1:]:
|
||||
print F.Page(arg, 'EN')
|
||||
F = PageFactory()
|
||||
for arg in sys.argv[1:]:
|
||||
print F.Page(arg)
|
||||
|
||||
|
||||
def usage():
|
||||
print "HTML.py version " + VERSION
|
||||
print "HTML.py version " + VERSION
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Error Checking Module
|
||||
|
||||
|
@ -45,7 +63,7 @@ class Lintadas:
|
|||
|
||||
File = Doc.Files[key]
|
||||
|
||||
if File.Local:
|
||||
if File.IsLocal:
|
||||
self.L.Log.Write(3, 'Checking filename ' + key)
|
||||
else:
|
||||
self.L.Log.Write(3, 'Skipping remote file ' + key)
|
||||
|
|
|
@ -1,11 +1,39 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Log Module
|
||||
|
||||
This module generates the system log for Lampadas.
|
||||
|
||||
Logs are assigned one of the following severities:
|
||||
|
||||
0 critical errors
|
||||
1 errors
|
||||
2 warnings
|
||||
3 system events
|
||||
4 debugging messages
|
||||
"""
|
||||
|
||||
from Config import config
|
||||
|
||||
# Modules ##################################################################
|
||||
|
||||
|
||||
|
@ -14,28 +42,34 @@ class Log:
|
|||
Write to the system log.
|
||||
"""
|
||||
|
||||
import Config
|
||||
|
||||
Config = Config.Config()
|
||||
import time
|
||||
|
||||
def __call__(self, level, message):
|
||||
self.Write(level, message)
|
||||
self.write(level, message)
|
||||
|
||||
def Write(self, level, message):
|
||||
if self.Config.LogLevel >= level:
|
||||
self.log = open(self.Config.LogFile, 'a+')
|
||||
self.log.write(message + "\n")
|
||||
def write(self, level, message):
|
||||
if config.log_level >= level:
|
||||
timestamp = self.time.time()
|
||||
logmessage = self.time.ctime(self.time.time()) + ' ' + message
|
||||
self.log = open(config.log_file, 'a+')
|
||||
self.log.write(logmessage + "\n")
|
||||
self.log.close
|
||||
if self.Config.LogConsole > 0:
|
||||
print message
|
||||
if config.log_console > 0:
|
||||
print logmessage
|
||||
|
||||
def Truncate(self):
|
||||
self.log = open(self.Config.LogFile, 'w+')
|
||||
def truncate(self):
|
||||
self.log = open(config.log_file, 'w+')
|
||||
self.log.close
|
||||
|
||||
if __name__ == "__main__":
|
||||
Log = Log()
|
||||
Log(1, 'level 1')
|
||||
Log(2, 'level 2')
|
||||
Log(3, 'level 3')
|
||||
|
||||
log = Log()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
config.log_level = 3
|
||||
config.log_sql = 1
|
||||
config.log_console = 1
|
||||
log.write(1, 'level 1')
|
||||
log.write(2, 'level 2')
|
||||
log.write(3, 'level 3')
|
||||
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Mirroring Module
|
||||
|
||||
|
@ -28,33 +46,99 @@ class Mirror:
|
|||
Lint = Lintadas()
|
||||
|
||||
def mirror_all(self):
|
||||
dockeys = self.Lint.L.Docs.keys()
|
||||
for dockey in dockeys:
|
||||
self.Lint.L.Log(3, 'Mirroring all documents')
|
||||
for dockey in self.Lint.L.Docs.keys():
|
||||
self.mirror_doc(dockey)
|
||||
self.write_main_makefile()
|
||||
|
||||
def mirror_doc(self, DocID):
|
||||
self.Lint.L.Log.Write(3, 'Mirroring document ' + str(DocID))
|
||||
self.Doc = self.Lint.L.Docs[DocID]
|
||||
|
||||
# decide if the document is remote
|
||||
#
|
||||
self.is_remote = 0
|
||||
filekeys = self.Doc.Files.keys()
|
||||
for filekey in filekeys:
|
||||
self.File = self.Doc.Files[filekey]
|
||||
if not self.File.Local:
|
||||
self.filename = self.File.Filename
|
||||
self.Lint.L.Log(3, 'mirroring ' + self.filename)
|
||||
self.basename = self.os.path.basename(self.filename)
|
||||
self.localdir = self.C.cache_dir + str(self.Doc.ID) + '/'
|
||||
if not self.os.access(self.localdir, self.os.F_OK):
|
||||
self.os.mkdir(self.localdir)
|
||||
self.localname = self.localdir + self.basename
|
||||
self.urllib.urlretrieve(self.File.Filename, self.localname)
|
||||
command = 'cd ' + self.localdir + '; gunzip -f ' + self.basename
|
||||
self.os.system(command)
|
||||
if not self.Doc.Files[filekey].IsLocal:
|
||||
self.is_remote = 1
|
||||
|
||||
# delete list of local files if document is remote
|
||||
#
|
||||
if self.is_remote:
|
||||
filekeys = self.Doc.Files.keys()
|
||||
for filekey in filekeys:
|
||||
if self.Doc.Files[filekey].Local:
|
||||
if self.Doc.Files[filekey].IsLocal:
|
||||
self.Doc.Files[filekey].Del()
|
||||
for file in self.os.listdir(self.localdir):
|
||||
self.Doc.Files.Add(self.Doc.ID, file)
|
||||
self.Lint.CheckDoc(DocID)
|
||||
|
||||
# mirror all files into cache, whether from remote
|
||||
# or local storage
|
||||
#
|
||||
# filename can look like: http://foo.org/foo.sgml
|
||||
# ftp://foo.org/foo.sgml
|
||||
# howto/docbook/big-memory-howto.sgml
|
||||
#
|
||||
for filekey in filekeys:
|
||||
|
||||
# create cache directory for this document
|
||||
#
|
||||
self.cachedir = self.C.cache_dir + str(self.Doc.ID) + '/'
|
||||
if not self.os.access(self.cachedir, self.os.F_OK):
|
||||
self.os.mkdir(self.cachedir)
|
||||
|
||||
self.File = self.Doc.Files[filekey]
|
||||
self.filename = self.File.Filename
|
||||
self.file_only = self.File.file_only
|
||||
self.cachename = self.cachedir + self.file_only
|
||||
|
||||
if self.File.IsLocal:
|
||||
|
||||
# It is expensive to copy local documents into a cache directory,
|
||||
# but it avoids publishing documents directly out of CVS.
|
||||
# Some publishing tools leave clutter in the directory on failure.
|
||||
#
|
||||
if not self.os.access(self.C.CVSRoot + self.filename, self.os.F_OK):
|
||||
self.Lint.L.Log(2, 'Cannot mirror missing file: ' + self.filename)
|
||||
continue
|
||||
self.Lint.L.Log(3, 'mirroring local file ' + self.filename)
|
||||
command = 'cd ' + self.cachedir + '; cp -pu ' + self.C.CVSRoot + self.filename + ' .'
|
||||
self.os.system(command)
|
||||
|
||||
else:
|
||||
try:
|
||||
self.Lint.L.Log(3, 'mirroring remote file ' + self.filename)
|
||||
# FIXME: self.urllib.urlretrieve(self.File.Filename, self.cachename)
|
||||
except IOError:
|
||||
self.Lint.L.Log(0, 'error retrieving remote file ' + self.filename)
|
||||
continue
|
||||
|
||||
if self.unpack(self.cachedir, self.file_only):
|
||||
for file in self.os.listdir(self.cachedir):
|
||||
if file[-5:] <> '.html':
|
||||
self.Doc.Files.Add(self.Doc.ID, file)
|
||||
|
||||
self.Lint.CheckDoc(DocID)
|
||||
|
||||
self.Lint.L.Log(3, 'Mirroring document ' + str(DocID) + ' complete.')
|
||||
|
||||
|
||||
def unpack(self, dir, file):
|
||||
"""
|
||||
Goes to the specified directory and unpacks a file.
|
||||
Returns 1 if an archive was identified and unpacked.
|
||||
Returns 0 if it was not a recognized archive.
|
||||
Supported archives are .tar, .gz and .tar.gz.
|
||||
"""
|
||||
cmd_start = 'cd ' + dir + '; '
|
||||
if file[-7:] == '.tar.gz':
|
||||
self.os.system(cmd_start + 'tar -zxf ' + file)
|
||||
return 1
|
||||
elif file[-4:] == '.tar':
|
||||
self.os.system(cmd_start + 'tar -xf ' + file)
|
||||
return 1
|
||||
elif file[-3:] == '.gz':
|
||||
self.os.system(cmd_start + 'gunzip -f ' + file)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1,76 +1,148 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
The URLParse module deciphers a Lampadas URL into its component parts.
|
||||
The API is documented in the Lampadas Programmer's Guide. A summary:
|
||||
|
||||
[Language/][doc/<ID>[/<format>]|author/<ID>|$topic/$class]
|
||||
"""
|
||||
|
||||
import string
|
||||
from DataLayer import lampadas
|
||||
|
||||
def splitterm(term, sep):
|
||||
"""
|
||||
Splits the term into 2 pieces according to the seperator,
|
||||
and returns them. If the term does not contain the sep,
|
||||
the second string the returned tuple wil be ''.
|
||||
"""
|
||||
|
||||
temp = string.split(term, sep, 1)
|
||||
if len(temp) > 1:
|
||||
return temp[0], temp[1]
|
||||
else:
|
||||
return temp[0], ''
|
||||
|
||||
|
||||
class URI:
|
||||
URI = ""
|
||||
Protocol = ""
|
||||
Server = ""
|
||||
Port = ""
|
||||
Language = ""
|
||||
Path = ""
|
||||
Filename = ""
|
||||
Parameter = ""
|
||||
Anchor = ""
|
||||
|
||||
def __init__(self, uri):
|
||||
def __init__(self, uri):
|
||||
|
||||
self.protocol = ""
|
||||
self.server = ""
|
||||
self.port = ""
|
||||
self.language = "EN"
|
||||
self.force_lang = 0
|
||||
self.path = ""
|
||||
self.service = ""
|
||||
self.format = ""
|
||||
self.filename = "home"
|
||||
self.id = 0
|
||||
self.parameter = ""
|
||||
self.anchor = ""
|
||||
|
||||
self.URI = uri
|
||||
if not uri:
|
||||
return
|
||||
|
||||
temp = uri
|
||||
|
||||
if temp[:7] == "http://":
|
||||
self.Protocol = "http://"
|
||||
temp = temp[7:]
|
||||
self.uri = uri
|
||||
|
||||
temp = uri
|
||||
if len(temp) == 0:
|
||||
return
|
||||
if temp[0] == '/':
|
||||
temp = temp[1:]
|
||||
|
||||
if len(temp) == 0:
|
||||
return
|
||||
if temp[-1] == '/':
|
||||
temp = temp[:-1]
|
||||
|
||||
temp = string.split(temp,"#")
|
||||
if len(temp) > 1:
|
||||
self.Anchor = temp[1]
|
||||
temp = temp[0]
|
||||
|
||||
temp = string.split(temp,"?")
|
||||
if len(temp) > 1:
|
||||
self.Parameter = temp[1]
|
||||
temp = temp[0]
|
||||
|
||||
temp = string.split(temp,"/")
|
||||
if len(temp) > 1:
|
||||
self.Filename = temp[-1]
|
||||
temp = string.join(temp[:len(temp)-1],"/")
|
||||
if temp.find('://') > 0:
|
||||
self.protocol, temp = splitterm(temp, '://')
|
||||
self.server, temp = splitterm(temp,'/')
|
||||
if self.server.find(':') > 0:
|
||||
self.server, self.port = splitterm(self.server, ':')
|
||||
if temp.find('#') > 0:
|
||||
temp, self.anchor = splitterm(temp, '#')
|
||||
if temp.find('?') > 0:
|
||||
temp, self.parameter = splitterm(temp, '?')
|
||||
|
||||
temp = string.split(temp, '/')
|
||||
|
||||
temp = string.split(temp,"/")
|
||||
if len(temp) > 1:
|
||||
self.Path = string.join(temp[1:],'/') + '/'
|
||||
temp = temp[0]
|
||||
if len(temp) > 0:
|
||||
lang = lampadas.Languages[temp[0]]
|
||||
if not lang == None:
|
||||
self.language = temp[0]
|
||||
temp = temp[1:]
|
||||
self.force_lang = 1
|
||||
|
||||
temp = string.split(temp,":")
|
||||
if len(temp) > 1:
|
||||
self.Port = temp[1]
|
||||
self.Server = temp[0]
|
||||
|
||||
if len(self.Path) > 1:
|
||||
if len(self.Path) == 2:
|
||||
self.Language = self.Path
|
||||
self.Path = ''
|
||||
elif self.Path[2] == '/':
|
||||
self.Language = self.Path[:2]
|
||||
self.Path = self.Path[2:]
|
||||
if len(temp) > 0:
|
||||
if temp[0] == 'doc' or temp[0] == 'editdoc':
|
||||
# FIXME:
|
||||
#
|
||||
# This really should eb using only a single attribute, 'Filename'.
|
||||
# The 'doc' kludge should use a regular page which then embeds document
|
||||
# content.
|
||||
if temp[0] == 'doc':
|
||||
self.service = temp[0]
|
||||
self.filename = ''
|
||||
else:
|
||||
self.service = ''
|
||||
self.filename = temp[0]
|
||||
temp = temp[1:]
|
||||
if len(temp) > 0:
|
||||
self.id = int(temp[0])
|
||||
temp = temp[1:]
|
||||
if len(temp) > 0:
|
||||
if temp[0] == 'xml' or temp[0] == 'html' or temp[0] == 'omf':
|
||||
self.format = temp[0]
|
||||
else:
|
||||
self.filename = temp[0]
|
||||
else:
|
||||
if len(temp) == 1:
|
||||
self.path = '/'
|
||||
if len(temp[0]) > 0:
|
||||
self.filename = temp[0]
|
||||
else:
|
||||
self.path = string.join(temp[:-1], '/')
|
||||
if len(temp[-1]) > 0:
|
||||
self.filename = temp[-1]
|
||||
|
||||
|
||||
# This is a tricky area, so leave this for testing when problems arise
|
||||
# due to strange URIs.
|
||||
# print "URI: [" + self.URI + "]"
|
||||
# print "Language: [" + self.Language + "]"
|
||||
# print "Protocol: [" + self.Protocol + "]"
|
||||
# print "Server: [" + self.Server + "]"
|
||||
# print "Port: [" + self.Port + "]"
|
||||
# print "Path: [" + self.Path + "]"
|
||||
# print "Filename: [" + self.Filename + "]"
|
||||
# print "Parameter: [" + self.Parameter + "]"
|
||||
# print "Anchor: [" + self.Anchor + "]"
|
||||
def printdebug(self):
|
||||
print "URI: [" + self.uri + "]"
|
||||
print "Protocol: [" + self.protocol + "]"
|
||||
print "Server: [" + self.server + "]"
|
||||
print "Port: [" + self.port + "]"
|
||||
print "Path: [" + self.path + "]"
|
||||
print "Language: [" + self.language + "]"
|
||||
print "Forced Language: [" + str(self.force_lang) + "]"
|
||||
print "Service: [" + self.service+ "]"
|
||||
print "ID [" + str(self.id) + "]"
|
||||
print "Format [" + str(self.format) + "]"
|
||||
print "Filename: [" + self.filename + "]"
|
||||
print "Parameter: [" + self.parameter + "]"
|
||||
print "Anchor: [" + self.anchor + "]"
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
foo = URI('http://localhost:8000/EN/editdoc/1/home#foo')
|
||||
import sys
|
||||
|
||||
foo = URI(sys.argv[1])
|
||||
#'http://localhost:8000/EN/editdoc/1/home?docid=1#foo')
|
||||
foo.printdebug()
|
||||
|
|
|
@ -1,22 +1,34 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas UnitTest Module
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import Config
|
||||
import Database
|
||||
import DataLayer
|
||||
import Converter
|
||||
#import HTML
|
||||
from Config import config
|
||||
from Database import db
|
||||
from DataLayer import lampadas
|
||||
from Log import log
|
||||
import commands
|
||||
|
||||
Config = Config.Config()
|
||||
DB = Database.Database()
|
||||
|
||||
L = DataLayer.Lampadas()
|
||||
|
||||
# Test Suite ###################################################################
|
||||
|
||||
#def TS():
|
||||
|
@ -27,350 +39,369 @@ L = DataLayer.Lampadas()
|
|||
|
||||
# Unit Tests ###################################################################
|
||||
|
||||
|
||||
class testConfigFile(unittest.TestCase):
|
||||
|
||||
def testConfigFIle(self):
|
||||
L.Log(3, 'testing Config file')
|
||||
assert Config.DBType == "pgsql", "DBType is not valid"
|
||||
assert Config.DBName == "lampadas", "Database name is not valid"
|
||||
assert Config.CVSRoot > ''
|
||||
L.Log(3, 'testing Config file done')
|
||||
def testConfigFIle(self):
|
||||
log(3, 'testing Config file')
|
||||
assert config.db_type == "pgsql", "DBType is not valid"
|
||||
assert config.db_name == "lampadas", "Database name is not valid"
|
||||
assert config.cvs_root > ''
|
||||
log(3, 'testing Config file done')
|
||||
|
||||
|
||||
class testDatabase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
DB.Connect(Config.DBType, Config.DBName)
|
||||
def setUp(self):
|
||||
DB.Connect(Config.DBType, Config.DBName)
|
||||
|
||||
def testDatabase(self):
|
||||
L.Log(3, 'testing database')
|
||||
assert not DB.Connection == None
|
||||
L.Log(3, 'testing database done')
|
||||
def testDatabase(self):
|
||||
log(3, 'testing database')
|
||||
assert not DB.Connection == None
|
||||
log(3, 'testing database done')
|
||||
|
||||
def testCursor(self):
|
||||
log(3, 'testing cursor')
|
||||
self.Cursor = DB.Cursor
|
||||
assert not self.Cursor == None
|
||||
log(3, 'testing cursor done')
|
||||
|
||||
def testCursor(self):
|
||||
L.Log(3, 'testing cursor')
|
||||
self.Cursor = DB.Cursor
|
||||
assert not self.Cursor == None
|
||||
L.Log(3, 'testing cursor done')
|
||||
|
||||
class testClasses(unittest.TestCase):
|
||||
|
||||
def testClasses(self):
|
||||
L.Log(3, 'testing classes')
|
||||
assert not L.Classes == None
|
||||
assert L.Classes.Count() > 0
|
||||
L.Log(3, 'testing classes done')
|
||||
def testClasses(self):
|
||||
log(3, 'testing classes')
|
||||
assert not L.Classes == None
|
||||
assert lampadas.Classes.Count() > 0
|
||||
log(3, 'testing classes done')
|
||||
|
||||
|
||||
class testConfig(unittest.TestCase):
|
||||
|
||||
def testConfig(self):
|
||||
L.Log(3, 'testing Config')
|
||||
assert not L.Config == None
|
||||
assert L.Config['project_short'] == 'LDP'
|
||||
L.Log(3, 'testing Config done')
|
||||
def testConfig(self):
|
||||
log(3, 'testing Config')
|
||||
assert not config == None
|
||||
assert config['project_short'] == 'LDP'
|
||||
log(3, 'testing Config done')
|
||||
|
||||
|
||||
class testDocs(unittest.TestCase):
|
||||
|
||||
def testDocs(self):
|
||||
L.Log(3, 'testing Docs')
|
||||
assert not L.Docs == None
|
||||
assert L.Docs.Count() > 0
|
||||
def testDocs(self):
|
||||
log(3, 'testing Docs')
|
||||
assert not lampadas.Docs == None
|
||||
assert lampadas.Docs.Count() > 0
|
||||
|
||||
DB.Exec("DELETE FROM document where title='testharness'")
|
||||
DB.Commit()
|
||||
|
||||
self.OldID = DB.Value('SELECT max(doc_id) from document')
|
||||
self.NewID = L.Docs.Add('testharness', 1, 1, 'DocBook', '4.1.2', '1.0', '2002-04-04', 'http://www.example.com/HOWTO.html', 'ISBN', 'N', 'N', '2002-04-05', '2002-04-10', 'http://www.home.com', 'N', 'GFDL', 'This is a document.', 'EN', 'fooseries')
|
||||
assert self.NewID > 0
|
||||
assert self.OldID + 1 == self.NewID
|
||||
|
||||
self.Doc = L.Doc(self.NewID)
|
||||
assert not self.Doc == None
|
||||
assert self.Doc.ID == self.NewID
|
||||
assert self.Doc.Title == 'testharness'
|
||||
assert self.Doc.FormatID == 1
|
||||
|
||||
L.Docs.Del(self.NewID)
|
||||
self.NewID = DB.Value('SELECT MAX(doc_id) from document')
|
||||
assert self.NewID == self.OldID
|
||||
DB.Exec("DELETE FROM document where title='testharness'")
|
||||
DB.Commit()
|
||||
|
||||
self.OldID = DB.Value('SELECT max(doc_id) from document')
|
||||
self.NewID = lampadas.Docs.Add('testharness', 1, 1, 'DocBook', '4.1.2', '1.0', '2002-04-04', 'http://www.example.com/HOWTO.html', 'ISBN', 'N', 'N', '2002-04-05', '2002-04-10', 'http://www.home.com', 'N', 'GFDL', 'This is a document.', 'EN', 'fooseries')
|
||||
assert self.NewID > 0
|
||||
assert self.OldID + 1 == self.NewID
|
||||
|
||||
self.Doc = lampadas.Doc(self.NewID)
|
||||
assert not self.Doc == None
|
||||
assert self.Doc.ID == self.NewID
|
||||
assert self.Doc.Title == 'testharness'
|
||||
assert self.Doc.FormatID == 1
|
||||
|
||||
lampadas.Docs.Del(self.NewID)
|
||||
self.NewID = DB.Value('SELECT MAX(doc_id) from document')
|
||||
assert self.NewID == self.OldID
|
||||
|
||||
keys = L.Docs.keys()
|
||||
for key in keys:
|
||||
self.Doc = L.Docs[key]
|
||||
assert self.Doc.ID == key
|
||||
L.Log(3, 'testing Docs done')
|
||||
keys = lampadas.Docs.keys()
|
||||
for key in keys:
|
||||
self.Doc = lampadas.Docs[key]
|
||||
assert self.Doc.ID == key
|
||||
log(3, 'testing Docs done')
|
||||
|
||||
def testMapping(self):
|
||||
L.Log(3, 'testing Docs Mapping')
|
||||
self.Doc = L.Docs[100]
|
||||
assert not self.Doc == None
|
||||
assert not self.Doc.Title == ''
|
||||
assert self.Doc.ID == 100
|
||||
self.Doc = L.Docs[2]
|
||||
assert self.Doc.ID == 2
|
||||
L.Log(3, 'testing Docs Mapping done')
|
||||
def testMapping(self):
|
||||
log(3, 'testing Docs Mapping')
|
||||
self.Doc = lampadas.Docs[100]
|
||||
assert not self.Doc == None
|
||||
assert not self.Doc.Title == ''
|
||||
assert self.Doc.ID == 100
|
||||
self.Doc = lampadas.Docs[2]
|
||||
assert self.Doc.ID == 2
|
||||
log(3, 'testing Docs Mapping done')
|
||||
|
||||
def testSave(self):
|
||||
log(3, 'testing Docs Save')
|
||||
self.Doc = lampadas.Docs[100]
|
||||
self.Title = self.Doc.Title
|
||||
self.Doc.Title = 'Foo'
|
||||
assert self.Doc.Title == 'Foo'
|
||||
self.Doc.Save()
|
||||
self.Doc2 = lampadas.Docs[100]
|
||||
assert self.Doc2.Title == 'Foo'
|
||||
|
||||
self.Doc.Title = self.Title
|
||||
assert self.Doc.Title == self.Title
|
||||
self.Doc.Save()
|
||||
self.Doc2 = lampadas.Docs[100]
|
||||
assert self.Doc2.Title == self.Title
|
||||
log(3, 'testing Docs Save done')
|
||||
|
||||
def testSave(self):
|
||||
L.Log(3, 'testing Docs Save')
|
||||
self.Doc = L.Docs[100]
|
||||
self.Title = self.Doc.Title
|
||||
self.Doc.Title = 'Foo'
|
||||
assert self.Doc.Title == 'Foo'
|
||||
self.Doc.Save()
|
||||
self.Doc2 = L.Docs[100]
|
||||
assert self.Doc2.Title == 'Foo'
|
||||
|
||||
self.Doc.Title = self.Title
|
||||
assert self.Doc.Title == self.Title
|
||||
self.Doc.Save()
|
||||
self.Doc2 = L.Docs[100]
|
||||
assert self.Doc2.Title == self.Title
|
||||
L.Log(3, 'testing Docs Save done')
|
||||
|
||||
class testDocErrs(unittest.TestCase):
|
||||
|
||||
def testDocErrs(self):
|
||||
L.Log(3, 'testing DocErrs')
|
||||
keys = L.Docs.keys()
|
||||
for key in keys:
|
||||
Doc = L.Docs[key]
|
||||
assert not Doc == None
|
||||
if Doc.Errs.Count() > 0:
|
||||
print "found a doc with errors"
|
||||
for Err in Doc.Errs:
|
||||
assert not Err == None
|
||||
assert Err.DocID == Doc.ID
|
||||
assert Err.ErrID > 1
|
||||
L.Log(3, 'testing DocErrs done')
|
||||
|
||||
def testDocErrs(self):
|
||||
log(3, 'testing DocErrs')
|
||||
keys = lampadas.Docs.keys()
|
||||
for key in keys:
|
||||
Doc = lampadas.Docs[key]
|
||||
assert not Doc == None
|
||||
if Doc.Errs.Count() > 0:
|
||||
log("found a doc with errors")
|
||||
for Err in Doc.Errs:
|
||||
assert not Err == None
|
||||
assert Err.DocID == Doc.ID
|
||||
assert Err.ErrID > 1
|
||||
log(3, 'testing DocErrs done')
|
||||
|
||||
|
||||
class testDocFiles(unittest.TestCase):
|
||||
|
||||
def testDocFiles(self):
|
||||
L.Log(3, 'testing DocFiles')
|
||||
Doc = L.Docs[100]
|
||||
assert not Doc == None
|
||||
assert Doc.Files.Count() > 0
|
||||
keys = Doc.Files.keys()
|
||||
for key in keys:
|
||||
File = Doc.Files[key]
|
||||
if File == None: break
|
||||
assert File.DocID == Doc.ID
|
||||
assert File.Filename > ''
|
||||
L.Log(3, 'testing DocFiles done')
|
||||
def testDocFiles(self):
|
||||
log(3, 'testing DocFiles')
|
||||
Doc = lampadas.Docs[100]
|
||||
assert not Doc == None
|
||||
assert Doc.Files.Count() > 0
|
||||
keys = Doc.Files.keys()
|
||||
for key in keys:
|
||||
File = Doc.Files[key]
|
||||
if File == None: break
|
||||
assert File.DocID == Doc.ID
|
||||
assert File.Filename > ''
|
||||
log(3, 'testing DocFiles done')
|
||||
|
||||
|
||||
class testDocRatings(unittest.TestCase):
|
||||
|
||||
def testDocRatings(self):
|
||||
L.Log(3, 'testing DocRatings')
|
||||
Doc = L.Docs[100]
|
||||
assert not Doc == None
|
||||
Doc.Ratings.Clear()
|
||||
assert Doc.Ratings.Count() == 0
|
||||
assert Doc.Rating == 0
|
||||
def testDocRatings(self):
|
||||
log(3, 'testing DocRatings')
|
||||
Doc = lampadas.Docs[100]
|
||||
assert not Doc == None
|
||||
Doc.Ratings.Clear()
|
||||
assert Doc.Ratings.Count() == 0
|
||||
assert Doc.Rating == 0
|
||||
|
||||
# Add UserID: 1 Rating: 5 -- Avg: 5
|
||||
# Add UserID: 1 Rating: 5 -- Avg: 5
|
||||
|
||||
Doc.Ratings.Add(1, 5)
|
||||
assert Doc.Ratings.Count() == 1
|
||||
assert Doc.Ratings.Average == 5
|
||||
assert Doc.Rating == 5
|
||||
Doc.Ratings.Add(1, 5)
|
||||
assert Doc.Ratings.Count() == 1
|
||||
assert Doc.Ratings.Average == 5
|
||||
assert Doc.Rating == 5
|
||||
|
||||
# Add UserID: 2 Rating: 7 -- Avg: 6
|
||||
|
||||
Doc.Ratings.Add(2, 7)
|
||||
assert Doc.Ratings.Count() == 2
|
||||
assert Doc.Ratings.Average == 6
|
||||
assert Doc.Rating == 6
|
||||
# Add UserID: 2 Rating: 7 -- Avg: 6
|
||||
|
||||
Doc.Ratings.Add(2, 7)
|
||||
assert Doc.Ratings.Count() == 2
|
||||
assert Doc.Ratings.Average == 6
|
||||
assert Doc.Rating == 6
|
||||
|
||||
# Del UserID: 1
|
||||
|
||||
Doc.Ratings.Del(1)
|
||||
assert Doc.Ratings.Count() == 1
|
||||
assert Doc.Ratings.Average == 7
|
||||
assert Doc.Rating == 7
|
||||
# Del UserID: 1
|
||||
|
||||
Doc.Ratings.Del(1)
|
||||
assert Doc.Ratings.Count() == 1
|
||||
assert Doc.Ratings.Average == 7
|
||||
assert Doc.Rating == 7
|
||||
|
||||
# Clear again
|
||||
# Clear again
|
||||
|
||||
Doc.Ratings.Clear()
|
||||
assert Doc.Ratings.Count() == 0
|
||||
assert Doc.Ratings.Average == 0
|
||||
assert Doc.Rating == 0
|
||||
log(3, 'testing DocRatings done')
|
||||
|
||||
Doc.Ratings.Clear()
|
||||
assert Doc.Ratings.Count() == 0
|
||||
assert Doc.Ratings.Average == 0
|
||||
assert Doc.Rating == 0
|
||||
L.Log(3, 'testing DocRatings done')
|
||||
|
||||
class testDocVersions(unittest.TestCase):
|
||||
|
||||
def testDocVersions(self):
|
||||
L.Log(3, 'testing DocVersions')
|
||||
keys = L.Docs.keys()
|
||||
found = 0
|
||||
for key in keys:
|
||||
Doc = L.Docs[key]
|
||||
assert not Doc == None
|
||||
if Doc.Versions.Count() > 0:
|
||||
found = 1
|
||||
vkeys = Doc.Versions.keys()
|
||||
for vkey in vkeys:
|
||||
Version = Doc.Versions[vkey]
|
||||
assert not Version == None
|
||||
assert Version.PubDate > ''
|
||||
assert Version.Initials > ''
|
||||
assert found == 1
|
||||
L.Log(3, 'testing DocVersions done')
|
||||
def testDocVersions(self):
|
||||
log(3, 'testing DocVersions')
|
||||
keys = lampadas.Docs.keys()
|
||||
found = 0
|
||||
for key in keys:
|
||||
Doc = lampadas.Docs[key]
|
||||
assert not Doc == None
|
||||
if Doc.Versions.Count() > 0:
|
||||
found = 1
|
||||
vkeys = Doc.Versions.keys()
|
||||
for vkey in vkeys:
|
||||
Version = Doc.Versions[vkey]
|
||||
assert not Version == None
|
||||
assert Version.PubDate > ''
|
||||
assert Version.Initials > ''
|
||||
assert found == 1
|
||||
log(3, 'testing DocVersions done')
|
||||
|
||||
|
||||
class testDTDs(unittest.TestCase):
|
||||
|
||||
def testDTDs(self):
|
||||
L.Log(3, 'testing DTDs')
|
||||
assert L.DTDs.Count() > 0
|
||||
assert not L.DTDs['DocBook'] == None
|
||||
L.Log(3, 'testing DTDs done')
|
||||
def testDTDs(self):
|
||||
log(3, 'testing DTDs')
|
||||
assert lampadas.DTDs.Count() > 0
|
||||
assert not lampadas.DTDs['DocBook'] == None
|
||||
log(3, 'testing DTDs done')
|
||||
|
||||
|
||||
class testFormats(unittest.TestCase):
|
||||
|
||||
def testFormats(self):
|
||||
L.Log(3, 'testing Formats')
|
||||
assert L.Formats.Count() > 0
|
||||
assert not L.Formats[1] == None
|
||||
assert not L.Formats[1].I18n == None
|
||||
assert not L.Formats[1].I18n['EN'] == None
|
||||
assert L.Formats[1].I18n['EN'].Name > ''
|
||||
assert L.Formats[1].I18n['EN'].Description > ''
|
||||
L.Log(3, 'testing Formats done')
|
||||
def testFormats(self):
|
||||
log(3, 'testing Formats')
|
||||
assert lampadas.Formats.Count() > 0
|
||||
assert not lampadas.Formats[1] == None
|
||||
assert not lampadas.Formats[1].I18n == None
|
||||
assert not lampadas.Formats[1].I18n['EN'] == None
|
||||
assert lampadas.Formats[1].I18n['EN'].Name > ''
|
||||
assert lampadas.Formats[1].I18n['EN'].Description > ''
|
||||
log(3, 'testing Formats done')
|
||||
|
||||
|
||||
class testLanguages(unittest.TestCase):
|
||||
|
||||
def testLanguages(self):
|
||||
L.Log(3, 'testing Languages')
|
||||
assert L.Languages['EN'].Supported
|
||||
assert L.Languages['EN'].I18n['EN'].Name == 'English'
|
||||
assert L.Languages['FR'].Supported
|
||||
assert L.Languages['FR'].I18n['EN'].Name == 'French'
|
||||
assert L.Languages.Count() == 136
|
||||
L.Log(3, 'testing Languages done')
|
||||
def testLanguages(self):
|
||||
log(3, 'testing Languages')
|
||||
assert lampadas.Languages['EN'].Supported
|
||||
assert lampadas.Languages['EN'].I18n['EN'].Name == 'English'
|
||||
assert lampadas.Languages['FR'].Supported
|
||||
assert lampadas.Languages['FR'].I18n['EN'].Name == 'French'
|
||||
assert lampadas.Languages.Count() == 136
|
||||
log(3, 'testing Languages done')
|
||||
|
||||
|
||||
class testPubStatuses(unittest.TestCase):
|
||||
|
||||
def testPubStatuses(self):
|
||||
L.Log(3, 'testing PubStatuses')
|
||||
assert not L.PubStatuses == None
|
||||
assert L.PubStatuses.Count() > 0
|
||||
assert not L.PubStatuses['A'] == None
|
||||
assert not L.PubStatuses['A'].I18n == None
|
||||
assert not L.PubStatuses['A'].I18n['EN'] == None
|
||||
assert L.PubStatuses['A'].I18n['EN'].Name > ''
|
||||
assert L.PubStatuses['A'].I18n['EN'].Description > ''
|
||||
L.Log(3, 'testing PubStatuses done')
|
||||
|
||||
def testPubStatuses(self):
|
||||
log(3, 'testing PubStatuses')
|
||||
assert not lampadas.PubStatuses == None
|
||||
assert lampadas.PubStatuses.Count() > 0
|
||||
assert not lampadas.PubStatuses['A'] == None
|
||||
assert not lampadas.PubStatuses['A'].I18n == None
|
||||
assert not lampadas.PubStatuses['A'].I18n['EN'] == None
|
||||
assert lampadas.PubStatuses['A'].I18n['EN'].Name > ''
|
||||
assert lampadas.PubStatuses['A'].I18n['EN'].Description > ''
|
||||
log(3, 'testing PubStatuses done')
|
||||
|
||||
|
||||
class testTopics(unittest.TestCase):
|
||||
|
||||
def testTopics(self):
|
||||
L.Log(3, 'testing Topics')
|
||||
assert not L.Topics == None
|
||||
assert L.Topics.Count() > 0
|
||||
keys = L.Topics.keys()
|
||||
for key in keys:
|
||||
Topic = L.Topics[key]
|
||||
assert Topic.Num > 0
|
||||
assert Topic.I18n['EN'].Name > ''
|
||||
L.Log(3, 'testing Topics done')
|
||||
def testTopics(self):
|
||||
log(3, 'testing Topics')
|
||||
assert not lampadas.Topics == None
|
||||
assert lampadas.Topics.Count() > 0
|
||||
keys = lampadas.Topics.keys()
|
||||
for key in keys:
|
||||
Topic = lampadas.Topics[key]
|
||||
assert Topic.Num > 0
|
||||
assert Topic.I18n['EN'].Name > ''
|
||||
log(3, 'testing Topics done')
|
||||
|
||||
|
||||
class testUsers(unittest.TestCase):
|
||||
|
||||
def testUsers(self):
|
||||
L.Log(3, 'testing Users')
|
||||
assert not L.Users == None
|
||||
assert L.Users.Count() > 0
|
||||
def testUsers(self):
|
||||
log(3, 'testing Users')
|
||||
assert not lampadas.Users == None
|
||||
assert lampadas.Users.Count() > 0
|
||||
|
||||
DB.Exec("DELETE FROM username where email='foo@example.com'")
|
||||
DB.Commit()
|
||||
|
||||
self.OldID = DB.Value('SELECT MAX(user_id) from username')
|
||||
self.NewID = lampadas.Users.Add('testuser', 'j', 'random', 'hacker', 'foo@example.com', 1, 1, 'pw', 'notes go here', 'default')
|
||||
assert self.NewID > 0
|
||||
assert self.OldID + 1 == self.NewID
|
||||
|
||||
self.User = lampadas.User(self.NewID)
|
||||
assert not self.User == None
|
||||
assert self.User.ID == self.NewID
|
||||
assert self.User.Username == 'testuser'
|
||||
assert self.User.Email == 'foo@example.com'
|
||||
|
||||
lampadas.Users.Del(self.NewID)
|
||||
self.NewID = DB.Value('SELECT MAX(user_id) from username')
|
||||
assert self.NewID == self.OldID
|
||||
log(3, 'testing Users done')
|
||||
|
||||
DB.Exec("DELETE FROM username where email='foo@example.com'")
|
||||
DB.Commit()
|
||||
|
||||
self.OldID = DB.Value('SELECT MAX(user_id) from username')
|
||||
self.NewID = L.Users.Add('testuser', 'j', 'random', 'hacker', 'foo@example.com', 1, 1, 'pw', 'notes go here', 'default')
|
||||
assert self.NewID > 0
|
||||
assert self.OldID + 1 == self.NewID
|
||||
|
||||
self.User = L.User(self.NewID)
|
||||
assert not self.User == None
|
||||
assert self.User.ID == self.NewID
|
||||
assert self.User.Username == 'testuser'
|
||||
assert self.User.Email == 'foo@example.com'
|
||||
|
||||
L.Users.Del(self.NewID)
|
||||
self.NewID = DB.Value('SELECT MAX(user_id) from username')
|
||||
assert self.NewID == self.OldID
|
||||
L.Log(3, 'testing Users done')
|
||||
|
||||
class testUserDocs(unittest.TestCase):
|
||||
|
||||
def testUserDocs(self):
|
||||
log(3, 'testing UserDocs')
|
||||
self.User = lampadas.User(11)
|
||||
assert len(self.User.Docs) > 0
|
||||
assert self.User.Docs.Count() > 0
|
||||
assert not self.User.Docs == None
|
||||
for UserDoc in self.User.Docs:
|
||||
assert not UserDoc == None
|
||||
assert not UserDoc.DocID == None
|
||||
assert UserDoc.DocID > 0
|
||||
assert UserDoc.DocID == UserDoc.ID
|
||||
assert UserDoc.Active == 1 or UserDoc.Active == 0
|
||||
log(3, 'testing UserDocs done')
|
||||
|
||||
def testUserDocs(self):
|
||||
L.Log(3, 'testing UserDocs')
|
||||
self.User = L.User(11)
|
||||
assert len(self.User.Docs) > 0
|
||||
assert self.User.Docs.Count() > 0
|
||||
assert not self.User.Docs == None
|
||||
for UserDoc in self.User.Docs:
|
||||
assert not UserDoc == None
|
||||
assert not UserDoc.DocID == None
|
||||
assert UserDoc.DocID > 0
|
||||
assert UserDoc.Active == 1 or UserDoc.Active == 0
|
||||
L.Log(3, 'testing UserDocs done')
|
||||
|
||||
class testConverter(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.C = Converter.Converter()
|
||||
|
||||
def run(self, dir, base, ext, output):
|
||||
self.filename = dir + base + ext
|
||||
self.xmlnew = dir + base + '.xml.new'
|
||||
self.md5new = dir + base + '.md5.new'
|
||||
self.md5old = dir + base + '.md5.old'
|
||||
|
||||
fd = open(self.xmlnew, 'w')
|
||||
fd.write(output + "\n")
|
||||
fd.close()
|
||||
|
||||
newchecksum = commands.getoutput('md5sum < ' + self.xmlnew)
|
||||
newchecksum = newchecksum + "\n"
|
||||
|
||||
fd = open(self.md5new, 'w')
|
||||
fd.write(newchecksum)
|
||||
fd.close()
|
||||
|
||||
fd = open(self.md5old, 'r')
|
||||
oldchecksum = fd.read()
|
||||
fd.close()
|
||||
|
||||
assert oldchecksum == newchecksum
|
||||
|
||||
def testWikiText(self):
|
||||
|
||||
output = self.C.wikitext('test/wt/Lampadas.wt')
|
||||
self.run('test/wt/', 'Lampadas', '.wt', output)
|
||||
|
||||
def testTexinfo(self):
|
||||
output = self.C.texinfo('test/texinfo/texinfo.txi')
|
||||
self.run('test/texinfo/', 'texinfo', '.txi', output)
|
||||
|
||||
def testDBSGML(self):
|
||||
output = self.C.dbsgml('test/db3.0sgml/RPM-HOWTO.sgml')
|
||||
self.run('test/db3.0sgml/', 'RPM-HOWTO', '.sgml', output)
|
||||
|
||||
output = self.C.dbsgml('test/db3.1sgml/XFree86-Second-Mouse.sgml')
|
||||
self.run('test/db3.1sgml/', 'XFree86-Second-Mouse', '.sgml', output)
|
||||
|
||||
output = self.C.dbsgml('test/db4.1sgml/Small-Memory.sgml')
|
||||
self.run('test/db4.1sgml/', 'Small-Memory', '.sgml', output)
|
||||
#class testConverter(unittest.TestCase):
|
||||
#
|
||||
# import Converter
|
||||
#
|
||||
# def setUp(self):
|
||||
# self.C = Converter.Converter()
|
||||
#
|
||||
# def run(self, dir, base, ext, output):
|
||||
# self.filename = dir + base + ext
|
||||
# self.xmlnew = dir + base + '.xml.new'
|
||||
# self.md5new = dir + base + '.md5.new'
|
||||
# self.md5old = dir + base + '.md5.old'
|
||||
#
|
||||
# fd = open(self.xmlnew, 'w')
|
||||
# fd.write(output + "\n")
|
||||
# fd.close()
|
||||
#
|
||||
# newchecksum = commands.getoutput('md5sum < ' + self.xmlnew)
|
||||
# newchecksum = newchecksum + "\n"
|
||||
#
|
||||
# fd = open(self.md5new, 'w')
|
||||
# fd.write(newchecksum)
|
||||
# fd.close()
|
||||
#
|
||||
# fd = open(self.md5old, 'r')
|
||||
# oldchecksum = fd.read()
|
||||
# fd.close()
|
||||
#
|
||||
# assert oldchecksum == newchecksum
|
||||
#
|
||||
# def testWikiText(self):
|
||||
#
|
||||
# output = self.C.wikitext('test/wt/Lampadas.wt')
|
||||
# self.run('test/wt/', 'Lampadas', '.wt', output)
|
||||
#
|
||||
# def testTexinfo(self):
|
||||
# output = self.C.texinfo('test/texinfo/texinfo.txi')
|
||||
# self.run('test/texinfo/', 'texinfo', '.txi', output)
|
||||
#
|
||||
# def testDBSGML(self):
|
||||
# output = self.C.dbsgml('test/db3.0sgml/RPM-HOWTO.sgml')
|
||||
# self.run('test/db3.0sgml/', 'RPM-HOWTO', '.sgml', output)
|
||||
#
|
||||
# output = self.C.dbsgml('test/db3.1sgml/XFree86-Second-Mouse.sgml')
|
||||
# self.run('test/db3.1sgml/', 'XFree86-Second-Mouse', '.sgml', output)
|
||||
#
|
||||
# output = self.C.dbsgml('test/db4.1sgml/Small-Memory.sgml')
|
||||
# self.run('test/db4.1sgml/', 'Small-Memory', '.sgml', output)
|
||||
|
||||
#class testHTML(unittest.TestCase):
|
||||
|
||||
|
||||
# def setUp(self):
|
||||
# self.HTML = HTML.HTMLFactory()
|
||||
# self.HTML = HTMlampadas.HTMLFactory()
|
||||
|
||||
# def testHTML(self):
|
||||
# assert not self.HTML.Page == None
|
||||
# assert self.HTML.Page('test', 'EN') > ''
|
||||
# assert not self.HTMlampadas.Page == None
|
||||
# assert self.HTMlampadas.Page('test', 'EN') > ''
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# This file is part of the Lampadas Documentation System.
|
||||
#
|
||||
# Copyright (c) 2000, 2001, 2002 David Merrill <david@lupercalia.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
|
||||
#
|
||||
"""
|
||||
Lampadas Web Objects Module
|
||||
|
||||
|
@ -12,15 +30,12 @@ should come through this layer.
|
|||
|
||||
from Globals import *
|
||||
from BaseClasses import *
|
||||
import Config
|
||||
import Database
|
||||
from Config import config
|
||||
from Database import db
|
||||
|
||||
|
||||
# Globals
|
||||
|
||||
Config = Config.Config()
|
||||
DB = Database.Database()
|
||||
DB.Connect(Config.DBType, Config.DBName)
|
||||
|
||||
|
||||
# Blocks
|
||||
|
@ -30,7 +45,7 @@ class Blocks(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT block_code FROM block"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -46,7 +61,7 @@ class Block:
|
|||
def Load(self, row):
|
||||
self.Code = trim(row[0])
|
||||
self.sql = "SELECT lang, block FROM block_i18n WHERE block_code=" + wsq(self.Code)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -68,7 +83,7 @@ class Sections(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT section_code FROM section"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -84,7 +99,7 @@ class Section:
|
|||
def Load(self, row):
|
||||
self.Code = trim(row[0])
|
||||
self.sql = "SELECT lang, section_name FROM section_i18n WHERE section_code=" + wsq(self.Code)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -106,7 +121,7 @@ class Pages(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT page_code, section_code, template_code FROM page"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -124,7 +139,7 @@ class Page:
|
|||
self.SectionCode = trim(row[1])
|
||||
self.TemplateCode = trim(row[2])
|
||||
self.sql = "SELECT lang, title, page FROM page_i18n WHERE page_code=" + wsq(self.Code)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -150,7 +165,7 @@ class Strings(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT string_code FROM string"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
row = self.cursor.fetchone()
|
||||
if row == None: break
|
||||
|
@ -169,7 +184,7 @@ class String:
|
|||
def Load(self, row):
|
||||
self.Code = trim(row[0])
|
||||
self.sql = "SELECT lang, string FROM string_i18n WHERE string_code=" + wsq(self.Code)
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
@ -193,7 +208,7 @@ class Templates(LampadasCollection):
|
|||
def __init__(self):
|
||||
self.data = {}
|
||||
self.sql = "SELECT template_code, template FROM template"
|
||||
self.cursor = DB.Select(self.sql)
|
||||
self.cursor = db.select(self.sql)
|
||||
while (1):
|
||||
self.row = self.cursor.fetchone()
|
||||
if self.row == None: break
|
||||
|
|
|
@ -15,14 +15,7 @@ H1 {
|
|||
letter-spacing: .05em;
|
||||
}
|
||||
|
||||
H2 {
|
||||
color: brown;
|
||||
font-family: times;
|
||||
font-size: 16pt;
|
||||
font-style: bold;
|
||||
letter-spacing: .05em;
|
||||
}
|
||||
|
||||
H2
|
||||
H2 SUP {
|
||||
font-size: 8pt;
|
||||
font-family: helvetica;
|
||||
|
@ -92,6 +85,18 @@ TABLE.layout TD {
|
|||
padding: 3;
|
||||
}
|
||||
|
||||
TABLE.revhistory {
|
||||
color: black;
|
||||
background-color: tan;
|
||||
border: solid brown;
|
||||
border-width: 1;
|
||||
}
|
||||
|
||||
TABLE.revhistory TH {
|
||||
padding: 5;
|
||||
}
|
||||
|
||||
|
||||
TABLE.navbar {
|
||||
border: solid brown;
|
||||
border-width: 0;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
xslprefix = /usr/local/share
|
||||
|
||||
INSTALLDIR = install -d
|
||||
INSTALLXSL = install -p -m 644
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
|
||||
install: all
|
||||
$(INSTALLDIR) $(xslprefix)/lampadas
|
||||
$(INSTALLDIR) $(xslprefix)/lampadas/xsl
|
||||
$(INSTALLXSL) *.xsl $(xslprefix)/lampadas/xsl
|
||||
|
||||
clean:
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'
|
||||
xmlns="http://www.w3.org/TR/xhtml1/transitional"
|
||||
exclude-result-prefixes="#default">
|
||||
|
||||
<!-- $Id$ -->
|
||||
|
||||
<!-- This stylesheet is based on the ldp-html-chunk.xsl stylesheet
|
||||
by Dan York -->
|
||||
|
||||
<!-- This stylesheet calls Norman Walsh's 'docbook.xsl' stylesheet
|
||||
and therefore generates MULTIPLE HTML FILES as output. -->
|
||||
|
||||
<!-- Note the the *order* of the import statements below is important and
|
||||
should not be changed. -->
|
||||
|
||||
<!-- Change this to the path to where you have installed Norman
|
||||
Walsh's XSL stylesheets -->
|
||||
<xsl:import href="/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/chunk.xsl"/>
|
||||
|
||||
<!-- Imports the common LDP customization layer. -->
|
||||
<xsl:import href="lampadas-html-common.xsl"/>
|
||||
|
||||
<!-- If there was some reason to override 'lampadas-html-common.xsl' or to
|
||||
perform any other customizations that affect *only* the generation
|
||||
of multiple HTML files, those templates or parameters could be
|
||||
entered here. -->
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,328 @@
|
|||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'
|
||||
xmlns="http://www.w3.org/TR/xhtml1/transitional"
|
||||
exclude-result-prefixes="#default"
|
||||
>
|
||||
|
||||
<!-- $Id -->
|
||||
|
||||
<!-- This stylesheet is based on ldp-html-common.xsl, an
|
||||
experimental stylesheet by Dan York:
|
||||
|
||||
This is an attempt to replicate the customizations done in ldp.dsl
|
||||
Each customization in ldp.dsl is listed in the order in which it
|
||||
appears (in ldp.dsl) with the corresponding XSLT template or setting
|
||||
below it. Where there is no XSLT code below an item, that particular
|
||||
customization of ldp.dsl is not yet supported here. Some additional
|
||||
options and features have been added and are noted as not being in
|
||||
ldp.dsl. The work on this stylesheet began 5 Jul 2001. -->
|
||||
|
||||
<!-- Note that this file, 'lampadas-html-common.xsl', is NOT intended to be
|
||||
called directly. Instead, you should call either of two stylesheets:
|
||||
'lampadas-html.xsl' or 'lampadas-html-chunk.xsl'. The former generates a SINGLE
|
||||
HTML file, while the latter performs "chunking" to generate MULTIPLE
|
||||
HTML files. Both of those files import the appropriate Norman Walsh
|
||||
stylesheet and then import this customization layer. -->
|
||||
|
||||
<!-- NOT IN LDP.DSL - This stylesheet supports the additional use of the
|
||||
"role" and "condition" attributes to the <author> tag. The XSLT template
|
||||
is listed later in the stylesheet, but the text lables are listed
|
||||
here in order to make localization of the stylesheet easier. Note
|
||||
that spaces *are* significant in the value, so you should have a
|
||||
space after the colon. -->
|
||||
|
||||
<xsl:variable name="maintainerlabel">Maintainer</xsl:variable>
|
||||
<xsl:variable name="editorlabel">Editor</xsl:variable>
|
||||
<xsl:variable name="translatorlabel">Translator</xsl:variable>
|
||||
<xsl:variable name="converterlabel">Converter</xsl:variable>
|
||||
<xsl:variable name="authorlabel">Author</xsl:variable>
|
||||
|
||||
|
||||
<!-- NOT IN LDP.DSL
|
||||
Creates header content in all generated HTML files -->
|
||||
|
||||
<xsl:template name="user.head.content">
|
||||
<xsl:param name="node" select="."/>
|
||||
<meta name="generator" content="Lampadas XSL $Revision$"/>
|
||||
<link rel="stylesheet" href="/css/default.css" type="text/css"/>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
<xsl:comment> Generated by Lampadas XSLT customization layer
|
||||
based on Dan York's hack of Norman Walsh's DocBook XSL stylesheets.
|
||||
More information at http://www.tldp.org/ </xsl:comment>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<!-- generate-legalnotice-link?
|
||||
Not currently supported in Norm's XSL stylesheets. Logged
|
||||
at SourceForge as a bug. -->
|
||||
|
||||
<!-- Should graphics be used for admonitions (notes, warnings)? 0 or 1 -->
|
||||
<xsl:param name="admon.graphics" select="0"/>
|
||||
|
||||
<!-- If using admon graphics (1 above), what is path to graphics?
|
||||
Should be the path relative to your document and MUST end with
|
||||
a trailing slash. Also, this parameter needs to be on a
|
||||
single line. -->
|
||||
<xsl:param name="admon.graphics.path">images/</xsl:param>
|
||||
|
||||
|
||||
<!-- Make funcsynopsis look pretty -->
|
||||
<xsl:param name="funcsynopsis.decoration" select="1" doc:type="boolean"/>
|
||||
|
||||
<!-- Extension for HTML files -->
|
||||
<xsl:param name="html.ext" select="'.html'"/>
|
||||
|
||||
<!-- Generate TOCs for book, article, part -->
|
||||
<xsl:param name="generate.book.toc" select="1" doc:type="boolean"/>
|
||||
<xsl:param name="generate.article.toc" select="1" doc:type="boolean"/>
|
||||
<xsl:param name="generate.part.toc" select="1" doc:type="boolean"/>
|
||||
|
||||
<!-- generate-book-titlepage -->
|
||||
|
||||
<!-- generate-article-titlepage -->
|
||||
|
||||
<!-- Equivalent to chunk-skip-first-element-list - forces TOC on separate page
|
||||
If 0, first sect is on page for chapter or article -->
|
||||
<xsl:param name="chunk.first.sections" select="'1'"/>
|
||||
|
||||
|
||||
<!-- NOT IN LDP.DSL -->
|
||||
<!-- Create chunks for top-level sections. If 0, chunks will only be
|
||||
created for chapters/appendixes, and NOT for sectx elements -->
|
||||
<xsl:param name="chunk.sections" select="'1'"/>
|
||||
|
||||
<!-- list-element-list - NO LONGER NEEDED - bug fix -->
|
||||
|
||||
<!-- Filename for the root chunk -->
|
||||
<xsl:param name="root.filename" select="'index'"/>
|
||||
|
||||
<!-- shade-verbatim
|
||||
I have created a function below that shades the verbatim sections.
|
||||
logic would need to be added to check if this is set.
|
||||
Norm has added parameters to his 1.44 stylesheets that support
|
||||
shading verbatim sections. However, it looks like it requires
|
||||
an attribute to a table to have verbatim shading. Needs to be
|
||||
explored further. -->
|
||||
|
||||
<!-- When chunking, use id attribute as filename? 0 or 1 -->
|
||||
<xsl:param name="use.id.as.filename" select="1"/>
|
||||
|
||||
<!-- graphic-extensions - NO LONGER NEEDED?? -->
|
||||
|
||||
<!-- default graphic filename extension -->
|
||||
<xsl:param name="graphic.default.extension" select="'.gif'" doc:type="string"/>
|
||||
|
||||
<!-- Should chapters be labeled? 0 or 1 -->
|
||||
<xsl:param name="chapter.autolabel" select="1"/>
|
||||
|
||||
<!-- Should sections be labeled? 0 or 1 -->
|
||||
<xsl:param name="section.autolabel" select="1"/>
|
||||
|
||||
<!-- Related to section labels, should those labels include the chapter
|
||||
number in them (i.e., 1.1, 1.2, 1.3, 1.4 )-->
|
||||
<xsl:param name="section.label.includes.component.label" select="1" doc:type="boolean"/>
|
||||
|
||||
<!-- To what depth (in sections) should the TOC go? -->
|
||||
<xsl:param name="toc.section.depth" select="3"/>
|
||||
|
||||
<!-- Custom 'emphasis' template to allow 'role="strong"' to
|
||||
also produce a bold item. -->
|
||||
<xsl:template match="emphasis">
|
||||
<xsl:choose>
|
||||
<xsl:when test="(@role='strong') or (@role='bold')">
|
||||
<xsl:call-template name="inline.boldseq"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="inline.italicseq"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- book-titlepage-recto-elements
|
||||
article-titlepage-recto-elements
|
||||
article-titlepage-recto-mode
|
||||
article-title
|
||||
|
||||
- Customizing these elements (for instance, to list what is on the
|
||||
title page) involves writing a layer for html/titlepage.templates.xml and the
|
||||
other files html/titlepage.xsl and html/titlepage.templates.xsl - Norm
|
||||
is doing something funky here and I haven't fully figured it out. -->
|
||||
|
||||
<!-- The remainder of ldp.dsl deals with changing the foreground and
|
||||
background colors of verbatim elements although in reading through the
|
||||
DSSSL it doesn't look like it actually changed the foreground colors.
|
||||
The changing of the background shading can be done at two locations
|
||||
(one numbered, one not) in the template below. -->
|
||||
|
||||
<!-- Custom template for programlisting, screen and synopsis to generate a gray
|
||||
background to the item. -->
|
||||
<xsl:template match="programlisting|screen|synopsis">
|
||||
<xsl:param name="suppress-numbers" select="'0'"/>
|
||||
<xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
|
||||
<xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
|
||||
|
||||
<xsl:if test="@id">
|
||||
<a href="{$id}"/>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="$suppress-numbers = '0'
|
||||
and @linenumbering = 'numbered'
|
||||
and $use.extensions != '0'
|
||||
and $linenumbering.extension != '0'">
|
||||
<xsl:variable name="rtf">
|
||||
<xsl:apply-templates/>
|
||||
</xsl:variable>
|
||||
<!-- Change the color bacground color in the line below. -->
|
||||
<table border="0" bgcolor="#E0E0E0" width="90%">
|
||||
<tr><td>
|
||||
<pre class="{name(.)}">
|
||||
<xsl:call-template name="number.rtf.lines">
|
||||
<xsl:with-param name="rtf" select="$rtf"/>
|
||||
</xsl:call-template>
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- Change the color bacground color in the line below. -->
|
||||
<table border="0" bgcolor="#E0E0E0" width="90%">
|
||||
<tr><td>
|
||||
<pre class="{name(.)}">
|
||||
<xsl:apply-templates/>
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- NOT IN LDP.DSL. Custom template to allow Maintainer to be a role in
|
||||
the Author element. It also checks for a "condition" attribute
|
||||
to the <author> element. If it finds the condition attribute, it
|
||||
copies VERBATIM the value of the attribute to be in front of the
|
||||
word Author or Maintainer. This is done to allow maximum flexibility.
|
||||
Note that an <xsl:text> element was necessary to put the space
|
||||
between the condition and the word Author or Maintainer. -->
|
||||
|
||||
<xsl:template match="author" mode="titlepage.mode">
|
||||
<!-- If there is a condition attribute, print it VERBATIM first -->
|
||||
<xsl:if test="@condition"><i><xsl:value-of select="@condition"/></i>
|
||||
<xsl:text> </xsl:text></xsl:if>
|
||||
<!-- Test to see if there is a role. If maintainer, print that. If not,
|
||||
assume it is an author. -->
|
||||
<table class="box"><tr><th colspan="2">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@role='maintainer'">
|
||||
<xsl:value-of select="$maintainerlabel"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@role='editor'">
|
||||
<xsl:value-of select="$editorlabel"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@role='translator'">
|
||||
<xsl:value-of select="$translatorlabel"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@role='converter'">
|
||||
<xsl:value-of select="$converterlabel"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$authorlabel"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</th></tr>
|
||||
<tr><td>
|
||||
<xsl:call-template name="person.name"/>
|
||||
</td><td>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./contrib"/>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./affiliation"/>
|
||||
</td></tr></table>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Custom template to allow roles to be assigned to the OtherCredit
|
||||
element. Roles are editor, translator, and converter. -->
|
||||
|
||||
<xsl:template match="othercredit" mode="titlepage.mode">
|
||||
<!-- If there is a condition attribute, print it VERBATIM first -->
|
||||
<xsl:if test="@condition"><i><xsl:value-of select="@condition"/></i>
|
||||
<xsl:text> </xsl:text></xsl:if>
|
||||
<!-- Test to see if there is a role. If no role is included,
|
||||
assume it is maintainer. -->
|
||||
<table class="box"><tr><th colspan="2">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@role='editor'">
|
||||
<xsl:value-of select="$editorlabel"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@role='translator'">
|
||||
<xsl:value-of select="$translatorlabel"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@role='converter'">
|
||||
<xsl:value-of select="$converterlabel"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$maintainerlabel"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</th></tr>
|
||||
<tr><td>
|
||||
<xsl:call-template name="person.name"/>
|
||||
</td><td>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./contrib"/>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./affiliation"/>
|
||||
</td></tr></table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="revhistory" mode="titlepage.mode">
|
||||
<xsl:variable name="numcols">
|
||||
<xsl:choose>
|
||||
<xsl:when test="//authorinitials">3</xsl:when>
|
||||
<xsl:otherwise>2</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
|
||||
<div class="{name(.)}">
|
||||
<table class="box" summary="Revision history">
|
||||
<tr>
|
||||
<th colspan="{$numcols}">
|
||||
<b>
|
||||
<xsl:call-template name="gentext">
|
||||
<xsl:with-param name="key" select="'RevHistory'"/>
|
||||
</xsl:call-template>
|
||||
</b>
|
||||
</th>
|
||||
</tr>
|
||||
<xsl:apply-templates mode="titlepage.mode">
|
||||
<xsl:with-param name="numcols" select="$numcols"/>
|
||||
</xsl:apply-templates>
|
||||
</table>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="pubdate" mode="titlepage.mode">
|
||||
<table class="box"><tr><th><xsl:value-of select="."/></th></tr></table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="abstract" mode="titlepage.mode">
|
||||
<table class="box">
|
||||
<tr><th>
|
||||
<xsl:call-template name="anchor"/>
|
||||
<xsl:call-template name="formal.object.heading">
|
||||
<xsl:with-param name="title">
|
||||
<xsl:apply-templates select="." mode="title.markup"/>
|
||||
</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</th></tr>
|
||||
<tr><td>
|
||||
<xsl:apply-templates mode="titlepage.mode"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="formal.object.heading">
|
||||
<xsl:apply-templates select="." mode="object.title.markup">
|
||||
<xsl:with-param name="allow-anchors" select="1"/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'
|
||||
xmlns="http://www.w3.org/TR/xhtml1/transitional"
|
||||
exclude-result-prefixes="#default">
|
||||
|
||||
<!-- $Id$ -->
|
||||
|
||||
<!-- This stylesheet is based on ldp-html.xsl by Dan York. -->
|
||||
|
||||
<!-- This stylesheet calls Norman Walsh's 'docbook.xsl' stylesheet
|
||||
and therefore generates a SINGLE HTML FILE as output. -->
|
||||
|
||||
<!-- Note the the *order* of the import statements below is important and
|
||||
should not be changed. -->
|
||||
|
||||
<!-- Change this to the path to where you have installed Norman
|
||||
Walsh's XSL stylesheets. -->
|
||||
<xsl:import href="/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/docbook.xsl"/>
|
||||
|
||||
<!-- Imports the common LDP customization layer. -->
|
||||
<xsl:import href="lampadas-html-common.xsl"/>
|
||||
|
||||
<!-- If there was some reason to override 'lampadas-html-common.xsl' or to
|
||||
perform any other customizations that affect *only* the generation
|
||||
of a single HTML file, those templates or parameters could be
|
||||
entered here. -->
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'
|
||||
xmlns="http://www.w3.org/TR/xhtml1/transitional"
|
||||
exclude-result-prefixes="#default">
|
||||
|
||||
<!-- $Id$ -->
|
||||
|
||||
<!-- This stylesheet is based on the ldp-print.xsl stylesheet
|
||||
written by Dan York.
|
||||
|
||||
<!-- Change this to the path to where you have installed Norman
|
||||
Walsh's XSL stylesheets. -->
|
||||
<xsl:import href="/usr/share/sgml/docbook/docbook-xsl-1.41/fo/docbook.xsl"/>
|
||||
|
||||
<!-- Customized parameters and templates go here. -->
|
||||
|
||||
</xsl:stylesheet>
|
Loading…
Reference in New Issue