mirror of https://github.com/tLDP/LDP
Add ldp graphic to credit the LDP.
Manually insert some extra files for one bit doc. Make database talk over network. Closes #89726. Added new splash page where you can select language. Added new template to support splash page. Extended stylesheets to support "floating" elements on splash page. All pages now *require* a language extension. New strings. Tell tidy to encode into UTF-8. Separated header into two blocks to make reformatting pages easier. Fixed a ton of th tags that should have been td tags. Fixed missing translation strings for error #7. Removed stylesheet selection per user, site configurable only for now. Some documentation updates. Made the way registered/admin/sysadmin access is determined more sane. Added step in Make process to convert to UTF-8. Closes #89719. Fixed Mirror, broken in SourceFiles refactoring. Fixed URLParse, broke URI.base calculation going to relative paths.
This commit is contained in:
parent
87c7dcf289
commit
219cc5366e
|
@ -34,13 +34,14 @@ class ConfigFileReadErrorException(Exception) :
|
|||
|
||||
class Config:
|
||||
"""
|
||||
Basic configuration options (dbname, dbtype), used to know where we can find
|
||||
Basic configuration options (db_name, db_type), used to know where we can find
|
||||
the database.
|
||||
"""
|
||||
|
||||
config_file = ''
|
||||
db_type = ''
|
||||
db_name = ''
|
||||
db_host = ''
|
||||
log_file = ''
|
||||
log_level = 0
|
||||
log_sql = ''
|
||||
|
@ -75,6 +76,7 @@ class Config:
|
|||
|
||||
self.db_type = self.read_var('DB', 'dbtype')
|
||||
self.db_name = self.read_var('DB', 'dbname')
|
||||
self.db_host = self.read_var('DB', 'dbhost')
|
||||
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'))
|
||||
|
@ -105,6 +107,7 @@ class Config:
|
|||
print "config_file=" + self.config_file
|
||||
print "db_type=" + self.db_type
|
||||
print "db_name=" + self.db_name
|
||||
print "db_host=" + self.db_host
|
||||
print "log_file=" + self.log_file
|
||||
print "log_level=" + str(self.log_level)
|
||||
print "log_sql=" + str(self.log_sql)
|
||||
|
|
|
@ -1148,8 +1148,8 @@ class Languages(LampadasCollection):
|
|||
row = cursor.fetchone()
|
||||
if row==None: break
|
||||
lang_code = trim(row[0])
|
||||
language = self[lang_code]
|
||||
lang = trim(row[1])
|
||||
lang = trim(row[1])
|
||||
language = self[lang_code]
|
||||
language.name[lang] = trim(row[2])
|
||||
|
||||
class Language:
|
||||
|
|
|
@ -117,18 +117,18 @@ class Database:
|
|||
|
||||
class PgSQLDatabase(Database):
|
||||
|
||||
def __init__(self,db_name):
|
||||
def __init__(self, db_name, db_host):
|
||||
from pyPgSQL import PgSQL
|
||||
self.connection = PgSQL.connect(database=db_name)
|
||||
self.connection = PgSQL.connect(database=db_name, host=db_host)
|
||||
self.connection.autocommit = AUTOCOMMIT
|
||||
|
||||
class MySQLDatabase(Database):
|
||||
|
||||
def __init__(self,db_name):
|
||||
def __init__(self, db_name, db_host):
|
||||
from pyMySQL import MySQL
|
||||
self.connection = MySQL.connection(db_name=db_name)
|
||||
|
||||
def get_database(db_type, db_name):
|
||||
def get_database(db_type, db_name, db_host):
|
||||
"""
|
||||
Connect to the database specified in Config.
|
||||
|
||||
|
@ -137,13 +137,13 @@ def get_database(db_type, db_name):
|
|||
if db_name=='':
|
||||
raise UnknownDBException('Database name not specified')
|
||||
elif db_type=='pgsql':
|
||||
db = PgSQLDatabase(db_name)
|
||||
db = PgSQLDatabase(db_name, db_host)
|
||||
elif db_type=='mysql':
|
||||
db = MySQLDatabase(db_name)
|
||||
db = MySQLDatabase(db_name, db_host)
|
||||
else:
|
||||
raise UnknownDBException('Unknown database type %s' % db_type)
|
||||
raise UnknownDBException('Unknown database type %s, host is %s' % (db_type, db_host))
|
||||
return db
|
||||
|
||||
log(2, ' **********Initializing DataLayer**********')
|
||||
db = get_database(config.db_type, config.db_name)
|
||||
db = get_database(config.db_type, config.db_name, config.db_host)
|
||||
|
||||
|
|
|
@ -130,7 +130,14 @@ class PageFactory:
|
|||
elif token=='title':
|
||||
newstring = page.title[uri.lang]
|
||||
elif token=='body':
|
||||
newstring = page.page[uri.lang]
|
||||
if page.only_registered==1 and sessions.session==None:
|
||||
newstring = '|blknopermission|'
|
||||
elif page.only_admin==1 and (sessions.session==None or sessions.session.user.admin==0):
|
||||
newstring = '|blknopermission|'
|
||||
elif page.only_sysadmin==1 and (sessions.session==None or sessions.session.user.sysadmin==0):
|
||||
newstring = '|blknopermission|'
|
||||
else:
|
||||
newstring = page.page[uri.lang]
|
||||
elif token=='base':
|
||||
newstring = 'http://' + config.hostname
|
||||
if config.port > '':
|
||||
|
@ -285,6 +292,8 @@ class PageFactory:
|
|||
newstring = tables.errors(uri)
|
||||
elif token=='tabsearch':
|
||||
newstring = tables.tabsearch(uri)
|
||||
elif token=='tabsplashlanguages':
|
||||
newstring = tables.tabsplashlanguages(uri)
|
||||
|
||||
# Blocks and Strings
|
||||
if newstring==None:
|
||||
|
|
|
@ -28,6 +28,7 @@ This module writes out a Makefile for every document in the cache.
|
|||
|
||||
from Globals import *
|
||||
from DataLayer import lampadas
|
||||
from SourceFiles import sourcefiles
|
||||
from Config import config
|
||||
from Lintadas import lintadas
|
||||
from Log import log
|
||||
|
@ -69,17 +70,20 @@ class Makefile:
|
|||
return
|
||||
|
||||
for file in doc.files.keys():
|
||||
file = doc.files[file]
|
||||
if file.top==1 and file.errors.count()==0:
|
||||
docfile = doc.files[file]
|
||||
sourcefile = sourcefiles[file]
|
||||
if docfile.top==1 and sourcefile.errors.count()==0:
|
||||
|
||||
log(3, 'Found top file: ' + file.filename)
|
||||
dbsgmlfile = file.basename + '.db.sgml'
|
||||
xmlfile = file.basename + '.xml'
|
||||
tidyxmlfile = file.basename + '.tidy.xml'
|
||||
htmlfile = file.basename + '.html'
|
||||
log(3, 'Found top file: ' + sourcefile.filename)
|
||||
dbsgmlfile = sourcefile.basename + '.db.sgml'
|
||||
xmlfile = sourcefile.basename + '.xml'
|
||||
utfxmlfile = sourcefile.basename + '.utf.xml'
|
||||
utftempxmlfile = sourcefile.basename + '.utf.temp.xml'
|
||||
tidyxmlfile = sourcefile.basename + '.tidy.xml'
|
||||
htmlfile = sourcefile.basename + '.html'
|
||||
indexfile = 'index.html'
|
||||
txtfile = file.basename + '.txt'
|
||||
omffile = file.basename + '.omf'
|
||||
txtfile = sourcefile.basename + '.txt'
|
||||
omffile = sourcefile.basename + '.omf'
|
||||
|
||||
Makefile = WOStringIO('# File generated by Makefile.py\n' \
|
||||
'# Do not hand edit.\n\n' \
|
||||
|
@ -87,11 +91,11 @@ class Makefile:
|
|||
'rebuild:\tclean build\n\n' \
|
||||
'build:\tdbsgml xml tidyxml html index text omf\n\n' \
|
||||
'clean:\n')
|
||||
if doc.format_code<>'text':
|
||||
if sourcefile.format_code<>'text':
|
||||
Makefile.write('\trm -f %s\n' % txtfile)
|
||||
if doc.format_code<>'html':
|
||||
if sourcefile.format_code<>'html':
|
||||
Makefile.write('\trm -f *.html\n')
|
||||
if doc.format_code<>'xml':
|
||||
if sourcefile.format_code<>'xml':
|
||||
Makefile.write('\trm -f *.xml\n')
|
||||
Makefile.write('\trm -f %s\n' % dbsgmlfile)
|
||||
Makefile.write('\trm -f %s\n' % tidyxmlfile)
|
||||
|
@ -101,13 +105,13 @@ class Makefile:
|
|||
'\n')
|
||||
|
||||
# WikiText
|
||||
if file.format_code=='wikitext':
|
||||
if sourcefile.format_code=='wikitext':
|
||||
Makefile.write('dbsgml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\twt2db -n -s %s -o %s 2>>wt2db.log\n\n'
|
||||
% (file.file_only,
|
||||
dbsgmlfile, file.file_only,
|
||||
file.file_only, dbsgmlfile))
|
||||
% (sourcefile.file_only,
|
||||
dbsgmlfile, sourcefile.file_only,
|
||||
sourcefile.file_only, dbsgmlfile))
|
||||
|
||||
Makefile.write('xml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
|
@ -117,13 +121,13 @@ class Makefile:
|
|||
dbsgmlfile, xmlfile))
|
||||
|
||||
# Text
|
||||
if file.format_code=='text':
|
||||
if sourcefile.format_code=='text':
|
||||
Makefile.write('dbsgml:\t%s\n\n'
|
||||
'%s:\t%s\n' \
|
||||
'\twt2db -n -s %s -o %s 2>>wt2db.log\n\n'
|
||||
% (dbsgmlfile,
|
||||
dbsgmlfile, file.file_only,
|
||||
file.file_only, dbsgmlfile))
|
||||
dbsgmlfile, sourcefile.file_only,
|
||||
sourcefile.file_only, dbsgmlfile))
|
||||
|
||||
Makefile.write('xml:\t%s\n\n'
|
||||
'%s:\t%s\n' \
|
||||
|
@ -133,14 +137,14 @@ class Makefile:
|
|||
dbsgmlfile, xmlfile))
|
||||
|
||||
# Texinfo
|
||||
if file.format_code=='texinfo':
|
||||
Makefile = Makefile + 'BUILD_XML = texi2db -f ' + file.file_only + ' -o ' + xmlfile + " 2>>texi2db.log\n"
|
||||
if sourcefile.format_code=='texinfo':
|
||||
Makefile = Makefile + 'BUILD_XML = texi2db -f ' + sourcefile.file_only + ' -o ' + xmlfile + " 2>>texi2db.log\n"
|
||||
Makefile.write('dbsgml:\t%s\n\n'
|
||||
'%s:\t%s\n' \
|
||||
'\ttexi2db -f %s -o %s 2>>texi2db.log\n\n'
|
||||
% (dbsgmlfile,
|
||||
dbsgmlfile, file.file_only,
|
||||
file.file_only, dbsgmlfile))
|
||||
dbsgmlfile, sourcefile.file_only,
|
||||
sourcefile.file_only, dbsgmlfile))
|
||||
|
||||
Makefile.write('xml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
|
@ -150,14 +154,14 @@ class Makefile:
|
|||
dbsgmlfile, xmlfile))
|
||||
|
||||
# LinuxDoc SGML
|
||||
if file.format_code=='sgml' and doc.dtd_code=='LinuxDoc':
|
||||
if sourcefile.format_code=='sgml' and sourcefile.dtd_code=='LinuxDoc':
|
||||
Makefile.write('dbsgml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\tsgmlnorm -d /usr/local/share/ld2db/docbook.dcl %s > expanded.sgml 2>>sgmlnorm.log\n' \
|
||||
'\tjade -t sgml -c /usr/local/share/ld2db/catalog -d /usr/local/share/ld2db/ld2db.dsl\\#db expanded.sgml > %s 2>>jade.log\n\n'
|
||||
% (dbsgmlfile,
|
||||
dbsgmlfile, file.file_only,
|
||||
file.file_only, dbsgmlfile))
|
||||
dbsgmlfile, sourcefile.file_only,
|
||||
sourcefile.file_only, dbsgmlfile))
|
||||
|
||||
Makefile.write('xml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
|
@ -167,27 +171,39 @@ class Makefile:
|
|||
dbsgmlfile, xmlfile))
|
||||
|
||||
# DocBook SGML
|
||||
if file.format_code=='sgml' and doc.dtd_code=='DocBook':
|
||||
if sourcefile.format_code=='sgml' and sourcefile.dtd_code=='DocBook':
|
||||
Makefile.write('dbsgml:\n\n' \
|
||||
'xml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\txmllint --sgml %s > %s 2>>xmllint.log\n\n\n'
|
||||
% (xmlfile,
|
||||
xmlfile, file.file_only,
|
||||
file.file_only, xmlfile))
|
||||
xmlfile, sourcefile.file_only,
|
||||
sourcefile.file_only, xmlfile))
|
||||
|
||||
# DocBook XML
|
||||
if file.format_code=='xml' and doc.dtd_code=='DocBook':
|
||||
if sourcefile.format_code=='xml' and sourcefile.dtd_code=='DocBook':
|
||||
Makefile.write('dbsgml:\n\n' \
|
||||
'xml:\n\n')
|
||||
|
||||
# Everybody gets encoded into UTF-8 here
|
||||
Makefile.write('utfxml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\ticonv -f %s -t %s %s > %s 2>>iconv.log\n'
|
||||
'\txmllint --encode UTF-8 %s > %s 2>>xmllint.log\n\n'
|
||||
% (utfxmlfile,
|
||||
utfxmlfile, xmlfile,
|
||||
'ISO-8859-15', 'UTF-8', xmlfile, utftempxmlfile,
|
||||
utftempxmlfile, utfxmlfile))
|
||||
|
||||
# Everybody gets xml tidied before processing further
|
||||
Makefile.write('tidyxml:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\ttidy -config /etc/lampadas/tidyrc -quiet -f tidy.log %s > %s\n\n'
|
||||
% (tidyxmlfile,
|
||||
tidyxmlfile, xmlfile,
|
||||
xmlfile, tidyxmlfile))
|
||||
tidyxmlfile, utfxmlfile,
|
||||
utfxmlfile, tidyxmlfile))
|
||||
|
||||
# Now we have good DocBook XML, generate all outputs
|
||||
Makefile.write('html:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\txsltproc --param quiet 1 --maxdepth 100 %s %s %s > %s 2>>xsltproc.log\n\n'
|
||||
|
@ -196,10 +212,10 @@ class Makefile:
|
|||
XSLTPROC_PARAMS, config.xslt_html, tidyxmlfile, htmlfile))
|
||||
Makefile.write('index:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\txsltproc --param quiet 1 --maxdepth 100 %s %s %s > %s 2>>xsltproc.log\n\n'
|
||||
'\txsltproc --param quiet 1 --maxdepth 100 %s %s %s 2>>xsltproc.log\n\n'
|
||||
% (indexfile,
|
||||
indexfile, tidyxmlfile,
|
||||
XSLTPROC_PARAMS, config.xslt_chunk, tidyxmlfile, htmlfile))
|
||||
XSLTPROC_PARAMS, config.xslt_chunk, tidyxmlfile))
|
||||
Makefile.write('text:\t%s\n\n' \
|
||||
'%s:\t%s\n' \
|
||||
'\tlynx --dump --nolist %s > %s 2>>lynx.log\n\n'
|
||||
|
@ -232,11 +248,12 @@ class Makefile:
|
|||
makeneeded = 0
|
||||
for docid in lampadas.docs.keys():
|
||||
doc = lampadas.docs[docid]
|
||||
if doc.errors.count()==0 and doc.files.error_count()==0:
|
||||
if doc.errors.count()==0 and doc.files.error_count==0:
|
||||
for file in doc.files.keys():
|
||||
file = doc.files[file]
|
||||
if file.top==1:
|
||||
# if (file.format_code=='sgml' and doc.dtd_code=='DocBook') or (file.format_code=='sgml' and doc.dtd_code=='LinuxDoc') or file.format_code=='xml' or file.format_code=='wikitext' or file.format_code=='text':
|
||||
docfile = doc.files[file]
|
||||
sourcefile = sourcefiles[file]
|
||||
if docfile.top==1:
|
||||
# if (sourcefile.format_code=='sgml' and sourcefile.dtd_code=='DocBook') or (sourcefile.format_code=='sgml' and sourcefile.dtd_code=='LinuxDoc') or sourcefile.format_code=='xml' or sourcefile.format_code=='wikitext' or sourcefile.format_code=='text':
|
||||
makeneeded = 1
|
||||
rebuildmake = rebuildmake + "\tcd " + str(docid) + "; $(MAKE) rebuild 2>>make.log\n"
|
||||
buildmake = buildmake + "\tcd " + str(docid) + "; $(MAKE) all 2>>make.log\n"
|
||||
|
|
|
@ -28,6 +28,7 @@ local Lampdas system.
|
|||
# Modules ##################################################################
|
||||
|
||||
from DataLayer import lampadas
|
||||
from SourceFiles import sourcefiles
|
||||
from Log import log
|
||||
from Config import config
|
||||
import urllib
|
||||
|
@ -52,27 +53,28 @@ class Mirror:
|
|||
doc = lampadas.docs[doc_id]
|
||||
|
||||
# decide if the document is remote
|
||||
local = 1
|
||||
docremote = 0
|
||||
filekeys = doc.files.keys()
|
||||
for filekey in filekeys:
|
||||
if doc.files[filekey].local==0:
|
||||
local = 0
|
||||
if sourcefiles[filekey].local==0:
|
||||
docremote = 1
|
||||
|
||||
# delete list of local files if document is remote
|
||||
if local==0:
|
||||
# If document has a single remote file,
|
||||
# delete list of local files.
|
||||
if docremote==1:
|
||||
filekeys = doc.files.keys()
|
||||
for filekey in filekeys:
|
||||
if doc.files[filekey].local:
|
||||
if sourcefiles[filekey].local==1:
|
||||
doc.files[filekey].delete()
|
||||
|
||||
# mirror all files into cache, whether from remote
|
||||
# or local storage
|
||||
#
|
||||
# filename can look like:
|
||||
# http://foo.org/foo.sgml Pull via HTTP
|
||||
# ftp://foo.org/foo.sgml Pull via FTP
|
||||
# file://foo.org/foo.sgml Local, but outside CVS
|
||||
# howto/docbook/big-memory-howto.sgml
|
||||
# http://foo.org/foo.sgml Pull via HTTP
|
||||
# ftp://foo.org/foo.sgml Pull via FTP
|
||||
# file://foo.org/foo.sgml Local, but outside CVS
|
||||
# howto/docbook/big-memory-howto.sgml In CVS tree
|
||||
#
|
||||
for filekey in filekeys:
|
||||
|
||||
|
@ -81,12 +83,13 @@ class Mirror:
|
|||
if not os.access(cachedir, os.F_OK):
|
||||
os.mkdir(cachedir)
|
||||
|
||||
file = doc.files[filekey]
|
||||
filename = file.localname
|
||||
file_only = file.file_only
|
||||
cachename = cachedir + file_only
|
||||
docfile = doc.files[filekey]
|
||||
sourcefile = sourcefiles[filekey]
|
||||
filename = sourcefile.localname
|
||||
file_only = sourcefile.file_only
|
||||
cachename = cachedir + file_only
|
||||
|
||||
if file.local==1:
|
||||
if sourcefile.local==1:
|
||||
|
||||
# It is expensive to copy local documents into a cache directory,
|
||||
# but it avoids publishing documents directly out of CVS.
|
||||
|
@ -101,7 +104,7 @@ class Mirror:
|
|||
else:
|
||||
try:
|
||||
log(3, 'mirroring remote file ' + filename)
|
||||
urllib.urlretrieve(file.filename, cachename)
|
||||
urllib.urlretrieve(sourcefile.filename, cachename)
|
||||
except IOError:
|
||||
log(0, 'error retrieving remote file ' + filename)
|
||||
continue
|
||||
|
|
|
@ -26,7 +26,7 @@ from WebLayer import lampadasweb
|
|||
from Widgets import widgets
|
||||
from Sessions import sessions
|
||||
from Lintadas import lintadas
|
||||
|
||||
import os
|
||||
|
||||
EDIT_ICON = '<img src="|uri.base|images/edit.png" alt="Edit" height="20" width="20" '\
|
||||
'border="0" hspace="5" vspace="0" align="top">'
|
||||
|
@ -65,52 +65,52 @@ class Tables:
|
|||
''' % (sessions.session.username, doc.id))
|
||||
box.write('''<table class="box" width="100%%">
|
||||
<tr><th colspan="6">|strdocdetails|</th></tr>
|
||||
<tr><th class="label">|strtitle|</th>
|
||||
<tr><td class="label">|strtitle|</td>
|
||||
<td colspan="5">
|
||||
<input type="text" name="title" style="width:100%%" value="%s"></td>
|
||||
</tr>''' % doc.title)
|
||||
box.write('<tr>')
|
||||
box.write('<th class="label">|strstatus|</th><td>' + widgets.pub_status_code(doc.pub_status_code, uri.lang) + '</td>\n')
|
||||
box.write('<th class="label">|strtype|</th><td>' + widgets.type_code(doc.type_code, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|strstatus|</td><td>' + widgets.pub_status_code(doc.pub_status_code, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|strtype|</td><td>' + widgets.type_code(doc.type_code, uri.lang) + '</td>\n')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strversion|</th><td><input type=text name="version" value="' + doc.version + '"></td>\n')
|
||||
box.write('<th class="label">|strshort_title|<td><input type=text name="short_title" value="' + doc.short_title + '"></td>\n')
|
||||
box.write('<td class="label">|strversion|</td><td><input type=text name="version" value="' + doc.version + '"></td>\n')
|
||||
box.write('<td class="label">|strshort_title|</td><td><input type=text name="short_title" value="' + doc.short_title + '"></td>\n')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strwriting|</th><td>' + widgets.review_status_code(doc.review_status_code, uri.lang) + '</td>\n')
|
||||
box.write('<th class="label">|straccuracy|</th><td>' + widgets.tech_review_status_code(doc.tech_review_status_code, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|strwriting|</td><td>' + widgets.review_status_code(doc.review_status_code, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|straccuracy|</td><td>' + widgets.tech_review_status_code(doc.tech_review_status_code, uri.lang) + '</td>\n')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strpub_date|</th><td><input type=text name="pub_date" maxlength="10" value="' + doc.pub_date + '"></td>\n')
|
||||
box.write('<th class="label">|strupdated|</th><td><input type=text name="last_update" value="' + doc.last_update + '"></td>\n')
|
||||
box.write('<td class="label">|strpub_date|</td><td><input type=text name="pub_date" maxlength="10" value="' + doc.pub_date + '"></td>\n')
|
||||
box.write('<td class="label">|strupdated|</td><td><input type=text name="last_update" value="' + doc.last_update + '"></td>\n')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strtickle_date|</th><td><input type=text name="tickle_date" value="' + doc.tickle_date + '"></td>')
|
||||
box.write('<th class="label">|strisbn|</th><td><input type=text name="isbn" value="' + doc.isbn + '"></td>')
|
||||
box.write('<td class="label">|strtickle_date|</td><td><input type=text name="tickle_date" value="' + doc.tickle_date + '"></td>')
|
||||
box.write('<td class="label">|strisbn|</td><td><input type=text name="isbn" value="' + doc.isbn + '"></td>')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strmaintained|</th><td>' + bool2yesno(doc.maintained) + '</td>\n')
|
||||
box.write('<th class="label">|strrating|</th><td>' + self.bar_graph(doc.rating, 10, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|strmaintained|</td><td>' + bool2yesno(doc.maintained) + '</td>\n')
|
||||
box.write('<td class="label">|strrating|</td><td>' + self.bar_graph(doc.rating, 10, uri.lang) + '</td>\n')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strformat|</th>')
|
||||
box.write('<td class="label">|strformat|</td>')
|
||||
if doc.format_code > '':
|
||||
box.write('<td>' + lampadas.formats[doc.format_code].name[uri.lang] + '</td>\n')
|
||||
else:
|
||||
box.write('<td></td>\n')
|
||||
box.write('<th class="label">|strdtd|</th><td>%s %s</td>' % (doc.dtd_code, doc.dtd_version))
|
||||
box.write('<td class="label">|strdtd|</td><td>%s %s</td>' % (doc.dtd_code, doc.dtd_version))
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strlanguage|</th><td>' + widgets.lang(doc.lang, uri.lang) + '</td>\n')
|
||||
box.write('<th class="label">|strmaint_wanted|</th><td>' + widgets.tf('maintainer_wanted', doc.maintainer_wanted, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|strlanguage|</td><td>' + widgets.lang(doc.lang, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|strmaint_wanted|</td><td>' + widgets.tf('maintainer_wanted', doc.maintainer_wanted, uri.lang) + '</td>\n')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strlicense|</th><td>' + widgets.license_code(doc.license_code, uri.lang))
|
||||
box.write('<td class="label">|strlicense|</td><td>' + widgets.license_code(doc.license_code, uri.lang))
|
||||
box.write(' <input type=text name=license_version size="6" value="' + doc.license_version + '"></td>\n')
|
||||
box.write('<th class="label">|strcopyright_holder|</th><td><input type=text name=copyright_holder value="' + doc.copyright_holder + '"></td>\n')
|
||||
box.write('<td class="label">|strcopyright_holder|</td><td><input type=text name=copyright_holder value="' + doc.copyright_holder + '"></td>\n')
|
||||
box.write('</tr>\n<tr>\n')
|
||||
box.write('<th class="label">|strtrans_master|<td colspan="3">' + widgets.sk_seriesid(doc.sk_seriesid, uri.lang) + '</td>\n')
|
||||
box.write('<td class="label">|strtrans_master|</td><td colspan="3">' + widgets.sk_seriesid(doc.sk_seriesid, uri.lang) + '</td>\n')
|
||||
box.write('''
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="label">|strabstract|</th>
|
||||
<td class="label">|strabstract|</td>
|
||||
<td colspan="5"><textarea name="abstract" rows="6" cols="40" style="width:100%%" wrap>%s</textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="label">|strshort_desc|</th>
|
||||
<td class="label">|strshort_desc|</td>
|
||||
<td colspan="5"><input type=text name="short_desc" style="width:100%%" value="%s"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -195,29 +195,30 @@ class Tables:
|
|||
box.write('<input type=hidden name="filename" size=30 style="width:100%" value="' + docfile.filename + '">\n')
|
||||
box.write('<tr>\n')
|
||||
if sourcefile.errors.count() > 0:
|
||||
box.write('<td class="sectionlabel error" colspan="6">' + docfile.filename + '</td>\n')
|
||||
box.write('<td class="sectionlabel error" colspan="6"><a href="%ssourcefile/%s%s">%s</a></td>\n'
|
||||
% (uri.base, docfile.filename, uri.lang_ext, docfile.filename))
|
||||
else:
|
||||
box.write('<td class="sectionlabel" colspan="6"><a href="|uri.base|sourcefile/' + docfile.filename + uri.lang_ext + '">' + docfile.filename + '</a></td>\n')
|
||||
box.write('<td class="sectionlabel" colspan="6"><a href="%ssourcefile/%s%s">%s</a></td>\n'
|
||||
% (uri.base, docfile.filename, uri.lang_ext, docfile.filename))
|
||||
box.write('</tr>\n')
|
||||
box.write('<tr>\n')
|
||||
box.write('<th class="label">|strprimary|</th>')
|
||||
box.write('<td class="label">|strprimary|</td>')
|
||||
box.write('<td>' + widgets.tf('top', docfile.top, uri.lang) + '</td>\n')
|
||||
box.write('<th class="label">|strfilesize|</th>')
|
||||
box.write('<td class="label">|strfilesize|</td>')
|
||||
box.write('<td>' + str(sourcefile.filesize) + '</td>\n')
|
||||
box.write('<th class="label">|strupdated|</th>')
|
||||
box.write('<td class="label">|strupdated|</td>')
|
||||
if sourcefile.modified > '':
|
||||
box.write('<td>' + sourcefile.modified + '</td>\n')
|
||||
else:
|
||||
box.write('<td>|strunknown|</td>\n')
|
||||
box.write('</tr>\n')
|
||||
box.write('<tr>\n')
|
||||
box.write('<th class="label">|strformat|</th>')
|
||||
box.write('<td class="label">|strformat|</td>')
|
||||
if sourcefile.format_code > '':
|
||||
box.write('<td>' + lampadas.formats[sourcefile.format_code].name[uri.lang] + '</td>\n')
|
||||
else:
|
||||
box.write('<td>|strunknown|</td>\n')
|
||||
box.write('<th class="label">|strfilemode|</th>')
|
||||
print sourcefile.filemode
|
||||
box.write('<td class="label">|strfilemode|</td>')
|
||||
box.write('<td>' + widgets.filemode(sourcefile.filemode) + '</td>\n')
|
||||
box.write('''
|
||||
<td><input type="checkbox" name="delete">|strdelete|</td>
|
||||
|
@ -233,7 +234,7 @@ class Tables:
|
|||
box.write('<td colspan="6"><input type="text" name="filename" size="30" style="width:100%"></td>\n')
|
||||
box.write('</tr>\n')
|
||||
box.write('<tr>\n')
|
||||
box.write('<th class="label">|strprimary|</th>')
|
||||
box.write('<td class="label">|strprimary|</td>')
|
||||
box.write('<td>' + widgets.tf('top', 0, uri.lang) + '</td>\n')
|
||||
box.write('<td></td>\n')
|
||||
box.write('<td></td>\n')
|
||||
|
@ -538,15 +539,14 @@ class Tables:
|
|||
box = box + '</table>\n'
|
||||
return box
|
||||
|
||||
|
||||
def letters(self, uri):
|
||||
log(3, 'Creating letter table')
|
||||
box = '<table class="box" width="100%"><tr>\n'
|
||||
for letter in string.uppercase:
|
||||
if letter==uri.letter:
|
||||
box = box + '<th>' + letter + '</th>\n'
|
||||
box = box + '<td>' + letter + '</td>\n'
|
||||
else:
|
||||
box = box + '<th><a href="|uri.base|' + uri.page_code + '/' + letter + '|uri.lang_ext|">' + letter + '</a></th>\n'
|
||||
box = box + '<td><a href="|uri.base|' + uri.page_code + '/' + letter + '|uri.lang_ext|">' + letter + '</a></td>\n'
|
||||
box = box + '</tr></table>\n'
|
||||
return box
|
||||
|
||||
|
@ -590,32 +590,34 @@ class Tables:
|
|||
box = '<form method=GET action="/data/save/newuser" name="user">\n'
|
||||
box = box + '<table class="box" width="100%">\n'
|
||||
box = box + '<tr><th colspan=2>|struserdetails|</th><th>|strcomments|</th></tr>\n'
|
||||
box = box + '<tr><th class="label">|strusername|</th>'
|
||||
box = box + '<tr><td class="label">|strusername|</td>'
|
||||
if user.username=='':
|
||||
box = box + '<td><input type=text name="username"></td>\n'
|
||||
else:
|
||||
box = box + '<td><input name="username" type=hidden value=' + uri.username + '>' + uri.username + '</td>\n'
|
||||
box = box + '<td rowspan=10 style="width:100%"><textarea name="notes" wrap=soft style="width:100%; height:100%">' + user.notes + '</textarea></td></tr>\n'
|
||||
box = box + '<tr><th class="label">|strfirst_name|</th><td><input type=text name=first_name size="15" value="' + user.first_name + '"></td></tr>\n'
|
||||
box = box + '<tr><th class="label">|strmiddle_name|</th><td><input type=text name=middle_name size="15" value="' + user.middle_name + '"></td></tr>\n'
|
||||
box = box + '<tr><th class="label">|strsurname|</th><td><input type=text name=surname size="15" value="' + user.surname + '"></td></tr>\n'
|
||||
box = box + '<tr><th class="label">|stremail|</th><td><input type=text name=email size="15" value="' + user.email + '"></td></tr>\n'
|
||||
box = box + '<tr><th class="label">|strstylesheet|</th><td><input type=text name=stylesheet size="12" value="' + user.stylesheet + '"></td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strfirst_name|</td><td><input type=text name=first_name size="15" value="' + user.first_name + '"></td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strmiddle_name|</td><td><input type=text name=middle_name size="15" value="' + user.middle_name + '"></td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strsurname|</td><td><input type=text name=surname size="15" value="' + user.surname + '"></td></tr>\n'
|
||||
box = box + '<tr><td class="label">|stremail|</td><td><input type=text name=email size="15" value="' + user.email + '"></td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strstylesheet|</td><td><input type=text name=stylesheet size="12" value="' + user.stylesheet + '"></td></tr>\n'
|
||||
if user.username=='':
|
||||
box = box + '<tr><th class="label">|strpassword|</th><td><input type=text name=password size="12"></td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strpassword|</td><td><input type=text name=password size="12"></td></tr>\n'
|
||||
else:
|
||||
if sessions.session:
|
||||
if sessions.session.user.admin==1 or sessions.session.user.sysadmin==1:
|
||||
box = box + '<tr><th class="label">|strpassword|</th><td>' + user.password + '</td></tr>\n'
|
||||
box = box + '<tr><th class="label">|strnewpassword|</th><td><input type=text name=password size="12"></td></tr>\n'
|
||||
if sessions.session.user and sessions.session.user.admin > 0 or sessions.session.user.sysadmin > 0:
|
||||
box = box + '<tr><th class="label">|stradmin|</th><td>' + widgets.tf('admin', user.admin, uri.lang) + '</td></tr>\n'
|
||||
box = box + '<tr><th class="label">|strsysadmin|</th><td>' + widgets.tf('sysadmin', user.sysadmin, uri.lang) + '</td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strpassword|</td><td>' + user.password + '</td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strnewpassword|</td><td><input type=text name=password size="12"></td></tr>\n'
|
||||
if sessions.session.user and (sessions.session.user.admin > 0 or sessions.session.user.sysadmin > 0):
|
||||
box = box + '<tr><td class="label">|stradmin|</td><td>' + widgets.tf('admin', user.admin, uri.lang) + '</td></tr>\n'
|
||||
else:
|
||||
box = box + '<input name="admin" type="hidden" value="' + str(user.admin) + '">\n'
|
||||
box = box + '<tr><td class="label">|stradmin|</td><td>' + bool2yesno(user.admin) + '</td></tr>\n'
|
||||
if sessions.session.user and sessions.session.user.sysadmin > 0:
|
||||
box = box + '<tr><td class="label">|strsysadmin|</td><td>' + widgets.tf('sysadmin', user.sysadmin, uri.lang) + '</td></tr>\n'
|
||||
else:
|
||||
box = box + '<input name="sysadmin" type="hidden" value="' + str(user.sysadmin) + '">\n'
|
||||
box = box + '<tr><th class="label">|stradmin|</th><td>' + bool2yesno(user.admin) + '</td></tr>\n'
|
||||
box = box + '<tr><th class="label">|strsysadmin|</th><td>' + bool2yesno(user.sysadmin) + '</td></tr>\n'
|
||||
box = box + '<tr><td class="label">|strsysadmin|</td><td>' + bool2yesno(user.sysadmin) + '</td></tr>\n'
|
||||
box = box + '<tr><td></td><td><input type=submit name=save value=|strsave|></td></tr>\n'
|
||||
box = box + '</table>\n'
|
||||
box = box + '</form>\n'
|
||||
|
@ -782,7 +784,7 @@ class Tables:
|
|||
def section_menu(self, uri, section_code):
|
||||
log(3, "Creating section menu: " + section_code)
|
||||
section = lampadasweb.sections[section_code]
|
||||
box = WOStringIO('<table class="navbox" width="210"><tr><th>%s</th></tr>\n' \
|
||||
box = WOStringIO('<table class="navbox"><tr><th>%s</th></tr>\n' \
|
||||
'<tr><td>' % section.name[uri.lang])
|
||||
keys = lampadasweb.pages.sort_by('sort_order')
|
||||
for key in keys:
|
||||
|
@ -828,19 +830,14 @@ class Tables:
|
|||
page_codes = lampadasweb.pages.sort_by('sort_order')
|
||||
for section_code in section_codes:
|
||||
section = lampadasweb.sections[section_code]
|
||||
if section.only_dynamic and lampadasweb.static:
|
||||
if section.static_count==0 and lampadasweb.static:
|
||||
continue
|
||||
if section.nonregistered_count==0 and sessions.session==None:
|
||||
continue
|
||||
if section.nonadmin_count==0 and (sessions.session==None or sessions.session.user.admin==0):
|
||||
continue
|
||||
if section.nonsysadmin_count==0 and (sessions.session==None or sessions.session.user.sysadmin==0):
|
||||
continue
|
||||
if section.only_registered or section.only_admin or section.only_sysadmin > 0:
|
||||
if sessions.session==None or section.registered_count==0:
|
||||
continue
|
||||
if section.only_admin > 0:
|
||||
if sessions.session==None: continue
|
||||
if (sessions.session.user.admin==0 and sessions.session.user.sysadmin==0) or (section.admin_count==0):
|
||||
continue
|
||||
if section.only_sysadmin > 0:
|
||||
if sessions.session==None: continue
|
||||
if sessions.session.user.sysadmin==0 or section.sysadmin_count==0:
|
||||
continue
|
||||
|
||||
box = box + '<tr><td class="label">' + section.name[uri.lang] + '</td><td>\n'
|
||||
for page_code in page_codes:
|
||||
|
@ -880,7 +877,7 @@ class Tables:
|
|||
|
||||
def topics(self, uri):
|
||||
log(3, 'Creating topics menu')
|
||||
box = WOStringIO('''<table class="navbox" width="210">
|
||||
box = WOStringIO('''<table class="navbox">
|
||||
<tr><th>|strtopics|</th></tr>
|
||||
<tr><td><ol>''')
|
||||
keys = lampadas.topics.sort_by('num')
|
||||
|
@ -920,7 +917,7 @@ class Tables:
|
|||
|
||||
def types(self, uri):
|
||||
log(3, 'Creating types menu')
|
||||
box = WOStringIO('''<table class="navbox" width="210">
|
||||
box = WOStringIO('''<table class="navbox">
|
||||
<tr><th>|strtypes|</th></tr>
|
||||
<tr><td>''')
|
||||
keys = lampadas.types.sort_by('sort_order')
|
||||
|
@ -936,7 +933,7 @@ class Tables:
|
|||
return ''
|
||||
if sessions.session:
|
||||
log(3, 'Creating active user box')
|
||||
box = '''<table class="navbox" width="210">
|
||||
box = '''<table class="navbox">
|
||||
<tr><th>|stractive_user|</th></tr>
|
||||
<form name="logout" action="/data/session/logout">
|
||||
<input name="username" type="hidden" value="%s">
|
||||
|
@ -950,7 +947,7 @@ class Tables:
|
|||
''' % sessions.session.username
|
||||
else:
|
||||
log(3, 'Creating login box')
|
||||
box = '''<table class="navbox" width="210">
|
||||
box = '''<table class="navbox">
|
||||
<tr><th colspan="2">|strlogin|</th></tr>
|
||||
<form name="login" action="/data/session/login" method="GET">
|
||||
<tr>
|
||||
|
@ -975,7 +972,7 @@ class Tables:
|
|||
def navsessions(self, uri):
|
||||
if sessions.session and sessions.session.user.admin > 0:
|
||||
log(3, 'Creating navsessions table')
|
||||
box = WOStringIO('''<table class="navbox" width="210">
|
||||
box = WOStringIO('''<table class="navbox">
|
||||
<tr><th>|strsessions|</th></tr>
|
||||
<tr><td>
|
||||
''')
|
||||
|
@ -1019,7 +1016,7 @@ class Tables:
|
|||
|
||||
def languages(self, uri):
|
||||
log(3, 'Creating languages table')
|
||||
box = WOStringIO('''<table class="navbox" width="210">
|
||||
box = WOStringIO('''<table class="navbox">
|
||||
<tr><th>|strlanguages|</th></tr>
|
||||
<tr><td>
|
||||
''')
|
||||
|
@ -1049,27 +1046,27 @@ class Tables:
|
|||
<table class="box">\n
|
||||
<form name="search" action="/data/search/document">
|
||||
<tr><th colspan="2">|strsearch|</th></tr>\n
|
||||
<tr><th class="label">|strtitle|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strstatus|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strtype|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strtopic|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strmaintained|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strmaint_wanted|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strlanguage|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strwriting|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|straccuracy|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strpub_date|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strupdated|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strtickle_date|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strisbn|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strrating|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strformat|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strdtd|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strlicense|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strcopyright_holder|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strtrans_master|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strabstract|</th><td>%s</td></tr>
|
||||
<tr><th class="label">|strshort_desc|</th><td>%s</td></tr>
|
||||
<tr><td class="label">|strtitle|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strstatus|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strtype|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strtopic|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strmaintained|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strmaint_wanted|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strlanguage|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strwriting|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|straccuracy|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strpub_date|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strupdated|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strtickle_date|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strisbn|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strrating|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strformat|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strdtd|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strlicense|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strcopyright_holder|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strtrans_master|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strabstract|</td><td>%s</td></tr>
|
||||
<tr><td class="label">|strshort_desc|</td><td>%s</td></tr>
|
||||
<tr><td></td><td><input type="submit" value="|strsearch|"></td></tr>
|
||||
</form>
|
||||
</table>
|
||||
|
@ -1111,4 +1108,23 @@ class Tables:
|
|||
'''
|
||||
return box
|
||||
|
||||
def tabsplashlanguages(self, uri):
|
||||
"""
|
||||
Creates a fancy splash page for selecting a language.
|
||||
"""
|
||||
log(3, 'Creating tabslashlanguages table')
|
||||
box = WOStringIO('<p class="hide"><div class="map">\n' \
|
||||
'<p id="p1">|strprojectshort|</p>\n')
|
||||
id = 1
|
||||
langkeys = lampadas.languages.keys()
|
||||
for langkey in langkeys:
|
||||
language = lampadas.languages[langkey]
|
||||
if language.supported==1:
|
||||
id = id + 1
|
||||
box.write('<p id="p%s"><a href="%s.%s.html">%s</a></p>\n'
|
||||
% (str(id), 'home', langkey.lower(), language.name[language.code]))
|
||||
box.write('</div>')
|
||||
return box.get_value()
|
||||
|
||||
tables = Tables()
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ class URI:
|
|||
def __init__(self, uri):
|
||||
|
||||
log(3, "parsing URI: " + uri)
|
||||
self.base = ''
|
||||
self.protocol = ""
|
||||
self.server = ""
|
||||
self.port = ""
|
||||
|
@ -70,8 +69,9 @@ class URI:
|
|||
|
||||
self.uri = uri
|
||||
|
||||
for i in range(self.uri.count('/')):
|
||||
self.base = self.base = '../'
|
||||
self.base = ''
|
||||
for i in range(self.uri.count('/') -1):
|
||||
self.base += '../'
|
||||
|
||||
protocol, host, path, params, query, fragment = urlparse.urlparse(uri)
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ class Section:
|
|||
self.nonregistered_count = int(db.read_value('SELECT COUNT(*) FROM page WHERE section_code=' + wsq(self.code) + ' AND only_registered=' + wsq('f') + ' AND only_admin=' + wsq('f') + ' AND only_sysadmin=' + wsq('f') + ''))
|
||||
self.nonadmin_count = int(db.read_value('SELECT COUNT(*) FROM page WHERE section_code=' + wsq(self.code) + ' AND only_admin=' + wsq('f') + ' AND only_sysadmin=' + wsq('f') + ''))
|
||||
self.nonsysadmin_count = int(db.read_value('SELECT COUNT(*) FROM page WHERE section_code=' + wsq(self.code) + ' AND only_sysadmin=' + wsq('f') + ''))
|
||||
print self.code + ': ' + str(self.nonregistered_count) + ', ' + str(self.nonsysadmin_count) + ', ' + str(self.nonadmin_count)
|
||||
sql = "SELECT lang, section_name FROM section_i18n WHERE section_code=" + wsq(self.code)
|
||||
cursor = db.select(sql)
|
||||
while (1):
|
||||
|
|
Loading…
Reference in New Issue